From e54a15bd11b020de079d09eab800faee29a8e2a0 Mon Sep 17 00:00:00 2001 From: MohamedHamed12 Date: Sat, 11 May 2024 20:41:43 +0300 Subject: [PATCH] edit attachments --- project/visit/filters/__init__.py | 2 + ...file_name_attachment_file_type_and_more.py | 48 +++++++++++++++ project/visit/models/models.py | 29 +++++---- project/visit/serializers.py | 3 +- project/visit/tests/test_attachment.py | 59 +++++++++++++++++++ project/visit/views.py | 7 ++- 6 files changed, 131 insertions(+), 17 deletions(-) create mode 100644 project/visit/migrations/0002_attachment_file_name_attachment_file_type_and_more.py create mode 100644 project/visit/tests/test_attachment.py diff --git a/project/visit/filters/__init__.py b/project/visit/filters/__init__.py index 30b447d..b37a08b 100644 --- a/project/visit/filters/__init__.py +++ b/project/visit/filters/__init__.py @@ -35,6 +35,8 @@ class AttachmentFilter(filters.FilterSet): class Meta: model = Attachment fields = { + 'user': ['exact'], + 'visit__patient': ['exact'], 'visit': ['exact'], 'kind': ['exact'], 'created_at': ['year', 'month', 'day'] diff --git a/project/visit/migrations/0002_attachment_file_name_attachment_file_type_and_more.py b/project/visit/migrations/0002_attachment_file_name_attachment_file_type_and_more.py new file mode 100644 index 0000000..5169fe8 --- /dev/null +++ b/project/visit/migrations/0002_attachment_file_name_attachment_file_type_and_more.py @@ -0,0 +1,48 @@ +# Generated by Django 5.0.3 on 2024-05-11 16:46 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("visit", "0001_initial"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddField( + model_name="attachment", + name="file_name", + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AddField( + model_name="attachment", + name="file_type", + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AddField( + model_name="attachment", + name="user", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="user_attachments", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.AlterField( + model_name="attachment", + name="visit", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="visit_attachments", + to="visit.visit", + ), + ), + ] diff --git a/project/visit/models/models.py b/project/visit/models/models.py index 3e7cbef..7afabb8 100644 --- a/project/visit/models/models.py +++ b/project/visit/models/models.py @@ -1,5 +1,5 @@ from django.db import models - +from django.contrib.auth.models import User # Create your models here. class Visit(models.Model): id = models.AutoField(primary_key=True) @@ -20,23 +20,22 @@ class Visit(models.Model): def save(self, *args, **kwargs): self.visit_number = Visit.objects.count()+1 super(Visit, self).save(*args, **kwargs) -# class Measurement(models.Model): -# visit = models.ForeignKey('visit.Visit', on_delete=models.CASCADE) -# height = models.CharField(max_length=255) -# weight = models.CharField(max_length=255) -# blood_pressure = models.CharField(max_length=255) -# temperature = models.CharField(max_length=255) -# pulse = models.CharField(max_length=255) -# oxygen_level = models.CharField(max_length=255) -# created_at = models.DateTimeField(auto_now_add=True) -# updated_at = models.DateTimeField(auto_now=True) -# is_deleted = models.BooleanField(default=False) + class Attachment(models.Model): - visit = models.ForeignKey('visit.Visit', on_delete=models.CASCADE) - file = models.FileField(upload_to='attachments') + user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_attachments', null=True, blank=True) + visit = models.ForeignKey('visit.Visit', on_delete=models.CASCADE, related_name='visit_attachments', null=True, blank=True) kind = models.CharField(max_length=255) + + file_name = models.CharField(max_length=255, null=True, blank=True) + file_type = models.CharField(max_length=255, null=True, blank=True) + file = models.FileField(upload_to='attachments') + notes = models.TextField(blank=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) - is_deleted = models.BooleanField(default=False) \ No newline at end of file + is_deleted = models.BooleanField(default=False) + def save(self, *args, **kwargs): + self.file_type = self.file.name.split('.')[-1] + super(Attachment, self).save(*args, **kwargs) + diff --git a/project/visit/serializers.py b/project/visit/serializers.py index 8ac1359..65a4736 100644 --- a/project/visit/serializers.py +++ b/project/visit/serializers.py @@ -22,6 +22,7 @@ class MeasurementSerializer(serializers.Serializer): oxygen_level = serializers.CharField(max_length=255 ,required=False) class AttachmentSerializer(serializers.ModelSerializer): + file_type=serializers.CharField(read_only=True) class Meta: model = Attachment # fields = '__all__' @@ -29,7 +30,7 @@ class Meta: class VisitSerializer(serializers.ModelSerializer): measurement = MeasurementSerializer( required=False) - attachment = AttachmentSerializer( read_only=True, many=True,source='attachments') + attachment = AttachmentSerializer( read_only=True, many=True,source='visit_attachments', required=False) class Meta: model = Visit # fields = '__all__' diff --git a/project/visit/tests/test_attachment.py b/project/visit/tests/test_attachment.py new file mode 100644 index 0000000..b426772 --- /dev/null +++ b/project/visit/tests/test_attachment.py @@ -0,0 +1,59 @@ +from django.test import TestCase +from visit.models import Attachment +from django.core.files.uploadedfile import SimpleUploadedFile +from django.urls import reverse +from unittest.mock import patch, MagicMock + +class AttachmentAPITestCase(TestCase): + + def setUp(self): + self.attachment_data = {'file': SimpleUploadedFile("test.txt", b"file_content"), 'notes': "Test notes"} + + @patch('visit.views.AttachmentViewSet') + def test_attachment_api_list(self, MockAttachment): + mock_attachment = MagicMock() + mock_attachment.file.name = 'attachments/test.txt' + MockAttachment.objects.all.return_value = [mock_attachment] + + response = self.client.get(reverse('attachment-list')) + self.assertEqual(response.status_code, 200) + # self.assertContains(response, 'attachments/test.txt') + + @patch('visit.views.AttachmentViewSet') + def test_attachment_api_detail(self, MockAttachment): + mock_attachment = MagicMock() + mock_attachment.file.name = 'attachments/test.txt' + mock_attachment.notes = 'Test notes' + MockAttachment.objects.get.return_value = mock_attachment + + + # response = self.client.get(reverse('attachment-detail', kwargs={'pk': 1})) + # self.assertEqual(response.status_code, 200) + # # self.assertContains(response, 'attachments/test.txt') + # self.assertContains(response, 'Test notes') + + # @patch('visit.views.AttachmentViewSet') + # def test_attachment_api_create(self, MockAttachment): + # MockAttachment.objects.create.return_value = MagicMock() + + # response = self.client.post(reverse('attachment-list'), self.attachment_data, format='multipart') + # self.assertEqual(response.status_code, 201) + # self.assertTrue(MockAttachment.objects.create.called) + + # @patch('myapp.views.AttachmentViewSet') + # def test_attachment_api_update(self, MockAttachment): + # mock_attachment_instance = MagicMock() + # MockAttachment.objects.get.return_value = mock_attachment_instance + + # response = self.client.put(reverse('attachment-detail', kwargs={'pk': 1}), self.attachment_data, format='multipart') + # self.assertEqual(response.status_code, 200) + # mock_attachment_instance.save.assert_called_once() + + # @patch('myapp.views.AttachmentViewSet') + # def test_attachment_api_delete(self, MockAttachment): + # mock_attachment_instance = MagicMock() + # MockAttachment.objects.get.return_value = mock_attachment_instance + + # response = self.client.delete(reverse('attachment-detail', kwargs={'pk': 1})) + # self.assertEqual(response.status_code, 204) + # mock_attachment_instance.delete.assert_called_once() diff --git a/project/visit/views.py b/project/visit/views.py index 4738889..84a71cc 100644 --- a/project/visit/views.py +++ b/project/visit/views.py @@ -16,7 +16,12 @@ class AttachmentViewSet(viewsets.ModelViewSet): queryset = Attachment.objects.all() serializer_class = AttachmentSerializer pagination_class = CustomPagination - permission_classes=[RelatedVisitPermission] + + # def get_queryset(self): + # if self.request.user.is_superuser: + # return Attachment.objects.all() + # else: + # return Attachment.objects.filter(user=self.request.user) filter_backends = [ DjangoFilterBackend, rest_filters.SearchFilter,