From a5d092c94e2fea26ace4e89acb66f5d1faac6593 Mon Sep 17 00:00:00 2001 From: milachae Date: Tue, 14 Mar 2023 13:32:48 +0100 Subject: [PATCH 01/12] #57: fix visit field in photo model --- backend/drtrottoir/models/photo.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/drtrottoir/models/photo.py b/backend/drtrottoir/models/photo.py index 855901e2..314a483e 100644 --- a/backend/drtrottoir/models/photo.py +++ b/backend/drtrottoir/models/photo.py @@ -1,16 +1,16 @@ from django.db import models -from .building import Building +from .visit import Visit IMAGE_STATES = ((1, 'Arrival'), (2, 'Departure'), (3, 'Extra')) class Photo(models.Model): # image = models.ImageField(verbose_name="image", upload_to="images/") Pillow needs to be set up - visit = models.ForeignKey(Building, verbose_name="id of visit", on_delete=models.CASCADE) + visit = models.ForeignKey(Visit, verbose_name="id of visit", on_delete=models.CASCADE) state = models.IntegerField(verbose_name="type of photo", choices=IMAGE_STATES) comment = models.TextField(verbose_name="comment on the photo") created_at = models.DateTimeField(verbose_name="time of creation") def __str__(self): - return f"{self.visit.name}, {self.created_at}" + return f"{self.visit}, {self.created_at}" From dfcf2504021687dc3b0bc934b76f85875df82f57 Mon Sep 17 00:00:00 2001 From: milachae Date: Wed, 15 Mar 2023 13:42:57 +0100 Subject: [PATCH 02/12] fix check_actions script --- check_actions | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/check_actions b/check_actions index 86f4e05c..39137c67 100755 --- a/check_actions +++ b/check_actions @@ -4,9 +4,9 @@ docker-compose down -v docker-compose up -d --build echo "--------------------------------- RUNNING TESTS ---------------------------------" -docker exec DrTrottoir-be-d python manage.py test -docker exec DrTrottoir-fe-d npm run jest:workflow +docker exec DrTrottoir-be python manage.py test +docker exec DrTrottoir-fe npm run jest:workflow echo "--------------------------------- RUNNING LINTERS ---------------------------------" -docker exec DrTrottoir-be-d flake8 backend/ drtrottoir/ -docker exec DrTrottoir-fe-d npm run lint \ No newline at end of file +docker exec DrTrottoir-be flake8 backend/ drtrottoir/ +docker exec DrTrottoir-fe npm run lint \ No newline at end of file From 2bb471e0cce13b1f48ebd6c6641bfe6ed929e07b Mon Sep 17 00:00:00 2001 From: milachae Date: Wed, 15 Mar 2023 15:09:42 +0100 Subject: [PATCH 03/12] #64: simple photo endpoint working --- backend/drtrottoir/serializers/__init__.py | 4 +++- .../drtrottoir/serializers/photo_serializer.py | 12 ++++++++++++ backend/drtrottoir/urls.py | 3 ++- backend/drtrottoir/views/__init__.py | 4 +++- backend/drtrottoir/views/photo_viewset.py | 15 +++++++++++++++ 5 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 backend/drtrottoir/serializers/photo_serializer.py create mode 100644 backend/drtrottoir/views/photo_viewset.py diff --git a/backend/drtrottoir/serializers/__init__.py b/backend/drtrottoir/serializers/__init__.py index 29011351..6c2bbc37 100644 --- a/backend/drtrottoir/serializers/__init__.py +++ b/backend/drtrottoir/serializers/__init__.py @@ -4,6 +4,7 @@ from .user_serializer import UserSerializer from .user_partial import UserPartialSerializer from .visit_serializer import VisitSerializer +from .photo_serializer import PhotoSerializer __all__ = [ BuildingSerializer, @@ -11,5 +12,6 @@ RegionSerializer, UserSerializer, UserPartialSerializer, - VisitSerializer + VisitSerializer, + PhotoSerializer ] diff --git a/backend/drtrottoir/serializers/photo_serializer.py b/backend/drtrottoir/serializers/photo_serializer.py new file mode 100644 index 00000000..45fdf7fd --- /dev/null +++ b/backend/drtrottoir/serializers/photo_serializer.py @@ -0,0 +1,12 @@ +from rest_framework import serializers +from drtrottoir.models import Photo + + +class PhotoSerializer(serializers.HyperlinkedModelSerializer): + """ + A serializer for photos + """ + + class Meta: + model = Photo + fields = '__all__' diff --git a/backend/drtrottoir/urls.py b/backend/drtrottoir/urls.py index b2230fc0..e934728b 100644 --- a/backend/drtrottoir/urls.py +++ b/backend/drtrottoir/urls.py @@ -1,13 +1,14 @@ from django.urls import path from rest_framework import routers from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView -from .views import BuildingViewSet, RegionViewSet, VisitViewSet, UserViewSet +from .views import BuildingViewSet, RegionViewSet, VisitViewSet, UserViewSet, PhotoViewSet router = routers.DefaultRouter() router.register(r'building', BuildingViewSet) router.register(r'region', RegionViewSet) router.register(r'visit', VisitViewSet) router.register(r'user', UserViewSet) +router.register(r'photo', PhotoViewSet) urlpatterns = [ path('user/auth/', TokenObtainPairView.as_view(), name='token_obtain_pair'), diff --git a/backend/drtrottoir/views/__init__.py b/backend/drtrottoir/views/__init__.py index fee65a6e..beeb2b46 100644 --- a/backend/drtrottoir/views/__init__.py +++ b/backend/drtrottoir/views/__init__.py @@ -2,10 +2,12 @@ from .region_viewset import RegionViewSet from .visit_viewset import VisitViewSet from .user_viewset import UserViewSet +from .photo_viewset import PhotoViewSet __all__ = [ BuildingViewSet, RegionViewSet, VisitViewSet, - UserViewSet + UserViewSet, + PhotoViewSet ] diff --git a/backend/drtrottoir/views/photo_viewset.py b/backend/drtrottoir/views/photo_viewset.py new file mode 100644 index 00000000..9234a7c1 --- /dev/null +++ b/backend/drtrottoir/views/photo_viewset.py @@ -0,0 +1,15 @@ +from rest_framework import viewsets +from rest_framework.permissions import IsAuthenticated +from drtrottoir.models import Photo +from drtrottoir.permissions.super_permission import SuperPermissionOrReadOnly +from drtrottoir.serializers import PhotoSerializer + + +class PhotoViewSet(viewsets.ModelViewSet): + """ + API endpoint that allows photos to be viewed or edited. + """ + + queryset = Photo.objects.all() + serializer_class = PhotoSerializer + permission_classes = [IsAuthenticated & SuperPermissionOrReadOnly] From ac894a5c95897c25ca82f70fc12b53cff9ace23e Mon Sep 17 00:00:00 2001 From: milachae Date: Wed, 15 Mar 2023 15:10:50 +0100 Subject: [PATCH 04/12] changes fixtures + added file/ in .gitignore --- .gitignore | 3 +++ backend/fixtures/init_data.json | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/.gitignore b/.gitignore index c22f4c75..e7c9f2ee 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Data files +backend/files + # IDE things .idea .vscode diff --git a/backend/fixtures/init_data.json b/backend/fixtures/init_data.json index 00442e35..8546180a 100644 --- a/backend/fixtures/init_data.json +++ b/backend/fixtures/init_data.json @@ -129,5 +129,15 @@ "user": 2, "comment": "Vuilbakken zijn buitengezet" } +}, +{ + "model": "drtrottoir.photo", + "pk": 1, + "fields": { + "visit": 1, + "state": "1", + "comment": "Alles gelukt", + "created_at": "2023-03-08T16:00:33Z" + } } ] From e81eaf4c56ce278a81423290b4eebed6bab30938 Mon Sep 17 00:00:00 2001 From: milachae Date: Wed, 15 Mar 2023 20:54:05 +0100 Subject: [PATCH 05/12] #64: add tests photo --- .../drtrottoir/tests/factories/__init__.py | 4 ++- .../tests/factories/photo_factory.py | 16 +++++++++++ .../tests/factories/visit_factory.py | 3 ++- .../drtrottoir/tests/views/test_building.py | 2 +- backend/drtrottoir/tests/views/test_photo.py | 27 +++++++++++++++++++ 5 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 backend/drtrottoir/tests/factories/photo_factory.py create mode 100644 backend/drtrottoir/tests/views/test_photo.py diff --git a/backend/drtrottoir/tests/factories/__init__.py b/backend/drtrottoir/tests/factories/__init__.py index 3bcd1b4b..3f6da60f 100644 --- a/backend/drtrottoir/tests/factories/__init__.py +++ b/backend/drtrottoir/tests/factories/__init__.py @@ -2,10 +2,12 @@ from .user_factory import DeveloperUserFactory from .building_factory import BuildingFactory from .visit_factory import VisitFactory +from .photo_factory import PhotoFactory __all__ = [ RegionFactory, DeveloperUserFactory, BuildingFactory, - VisitFactory + VisitFactory, + PhotoFactory ] diff --git a/backend/drtrottoir/tests/factories/photo_factory.py b/backend/drtrottoir/tests/factories/photo_factory.py new file mode 100644 index 00000000..43eadfc8 --- /dev/null +++ b/backend/drtrottoir/tests/factories/photo_factory.py @@ -0,0 +1,16 @@ +import random +from factory.django import DjangoModelFactory +import factory +from django.utils import timezone +from drtrottoir.models import Photo +from .visit_factory import VisitFactory + + +class PhotoFactory(DjangoModelFactory): + visit = factory.SubFactory(VisitFactory) + state = random.choice([0, 1, 2]) + comment = factory.Faker("sentence") + created_at = factory.Faker("date_time", tzinfo=timezone.utc) + + class Meta: + model = Photo diff --git a/backend/drtrottoir/tests/factories/visit_factory.py b/backend/drtrottoir/tests/factories/visit_factory.py index 6c6988a3..a2427122 100644 --- a/backend/drtrottoir/tests/factories/visit_factory.py +++ b/backend/drtrottoir/tests/factories/visit_factory.py @@ -1,3 +1,4 @@ +from django.utils import timezone from factory.django import DjangoModelFactory import factory @@ -8,7 +9,7 @@ class VisitFactory(DjangoModelFactory): user = factory.SubFactory(DeveloperUserFactory) building = factory.SubFactory(BuildingFactory) - arrival = factory.Faker("date_time") + arrival = factory.Faker("date_time", tzinfo=timezone.utc) comment = factory.Faker("sentence") class Meta: diff --git a/backend/drtrottoir/tests/views/test_building.py b/backend/drtrottoir/tests/views/test_building.py index 506d789b..03f24f84 100644 --- a/backend/drtrottoir/tests/views/test_building.py +++ b/backend/drtrottoir/tests/views/test_building.py @@ -7,7 +7,7 @@ class TestBuildingView(APITestCase): - """ Test module for GET single Region API """ + """ Test module for GET single Building API """ def setUp(self): self.building = BuildingFactory() diff --git a/backend/drtrottoir/tests/views/test_photo.py b/backend/drtrottoir/tests/views/test_photo.py new file mode 100644 index 00000000..b9f7f41e --- /dev/null +++ b/backend/drtrottoir/tests/views/test_photo.py @@ -0,0 +1,27 @@ +from rest_framework import status +from rest_framework.test import APITestCase +from django.urls import reverse + +from drtrottoir.serializers import PhotoSerializer +from drtrottoir.tests.factories import PhotoFactory, DeveloperUserFactory + + +class TestPhotoView(APITestCase): + """ Test module for GET single Photo API """ + + def setUp(self): + self.photo = PhotoFactory() + user = DeveloperUserFactory() + self.client.force_authenticate(user=user) + + def test_get(self): + response = self.client.get(reverse("photo-detail", kwargs={'pk': self.photo.pk})) + serializer = PhotoSerializer(self.photo, context={'request': response.wsgi_request}) + self.assertEqual(response.data, serializer.data) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + def test_get_fault(self): + response = self.client.get(reverse("photo-detail", kwargs={'pk': self.photo.pk+1})) + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + + From 1f9b2bd1d5ac357b888b015269f884581611a081 Mon Sep 17 00:00:00 2001 From: milachae Date: Wed, 15 Mar 2023 21:21:40 +0100 Subject: [PATCH 06/12] #64: add more tests --- backend/drtrottoir/tests/views/test_photo.py | 21 ++++++++++++++++++++ backend/drtrottoir/views/photo_viewset.py | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/backend/drtrottoir/tests/views/test_photo.py b/backend/drtrottoir/tests/views/test_photo.py index b9f7f41e..19b53cec 100644 --- a/backend/drtrottoir/tests/views/test_photo.py +++ b/backend/drtrottoir/tests/views/test_photo.py @@ -24,4 +24,25 @@ def test_get_fault(self): response = self.client.get(reverse("photo-detail", kwargs={'pk': self.photo.pk+1})) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + def test_delete(self): + response1 = self.client.delete('/api/photo/' + str(self.photo.pk) + "/", follow=True) + response2 = self.client.get(reverse("photo-detail", kwargs={'pk': self.photo.pk})) + self.assertEqual(response1.status_code, status.HTTP_204_NO_CONTENT) + self.assertEqual(response2.status_code, status.HTTP_404_NOT_FOUND) + + def test_delete_fault(self): + response = self.client.delete('/api/photo/', follow=True) + self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) + + def test_patch(self): + response1 = self.client.patch( + '/api/photo/' + str(self.photo.pk) + "/", + data={"comment": "nieuwe zin"}, + follow=True + ) + response2 = self.client.get(reverse("photo-detail", kwargs={'pk': self.photo.pk})) + + self.assertNotEqual(response1.data, self.photo) + self.assertEqual(response1.data["comment"], response2.data["comment"]) + diff --git a/backend/drtrottoir/views/photo_viewset.py b/backend/drtrottoir/views/photo_viewset.py index 9234a7c1..d23d16f4 100644 --- a/backend/drtrottoir/views/photo_viewset.py +++ b/backend/drtrottoir/views/photo_viewset.py @@ -1,7 +1,7 @@ from rest_framework import viewsets from rest_framework.permissions import IsAuthenticated from drtrottoir.models import Photo -from drtrottoir.permissions.super_permission import SuperPermissionOrReadOnly +from drtrottoir.permissions.user_permissions import SuperPermissionOrReadOnly from drtrottoir.serializers import PhotoSerializer From 21ce0419eb1796104b7004ef9b6c8dfd8dc63908 Mon Sep 17 00:00:00 2001 From: milachae Date: Thu, 16 Mar 2023 00:01:30 +0100 Subject: [PATCH 07/12] #57: first working photos with photos --- .gitignore | 1 + backend/backend/settings.py | 7 +++++-- backend/backend/urls.py | 4 +++- backend/drtrottoir/models/photo.py | 2 +- backend/drtrottoir/tests/factories/photo_factory.py | 1 + backend/drtrottoir/tests/factories/visit_factory.py | 1 - backend/drtrottoir/tests/views/test_photo.py | 4 ++-- backend/drtrottoir/views/photo_viewset.py | 2 ++ backend/fixtures/init_data.json | 11 +---------- backend/requirements.txt | 3 ++- backend/test_file.py | 0 11 files changed, 18 insertions(+), 18 deletions(-) delete mode 100644 backend/test_file.py diff --git a/.gitignore b/.gitignore index e7c9f2ee..a649584c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # Data files backend/files +backend/uploads # IDE things .idea diff --git a/backend/backend/settings.py b/backend/backend/settings.py index a8dbe428..683d6544 100644 --- a/backend/backend/settings.py +++ b/backend/backend/settings.py @@ -148,7 +148,7 @@ LANGUAGE_CODE = 'en-us' -TIME_ZONE = 'UTC' +TIME_ZONE = 'CET' USE_I18N = True @@ -158,9 +158,12 @@ # https://docs.djangoproject.com/en/4.1/howto/static-files/ STATIC_URL = 'static/' - STATIC_ROOT = BASE_DIR / "staticfiles" +MEDIA_URL = '/media/' +MEDIA_ROOT = BASE_DIR / 'uploads' + + # Default primary key field type # https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field diff --git a/backend/backend/urls.py b/backend/backend/urls.py index 5bb45e9c..ed300b1d 100644 --- a/backend/backend/urls.py +++ b/backend/backend/urls.py @@ -15,8 +15,10 @@ """ from django.contrib import admin from django.urls import include, path +from django.conf import settings +from django.conf.urls.static import static urlpatterns = [ path('api/', include('drtrottoir.urls')), path('admin/', admin.site.urls), -] +] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/backend/drtrottoir/models/photo.py b/backend/drtrottoir/models/photo.py index 314a483e..a38fc0e5 100644 --- a/backend/drtrottoir/models/photo.py +++ b/backend/drtrottoir/models/photo.py @@ -6,7 +6,7 @@ class Photo(models.Model): - # image = models.ImageField(verbose_name="image", upload_to="images/") Pillow needs to be set up + image = models.ImageField(verbose_name="image", upload_to="images/", null=True) visit = models.ForeignKey(Visit, verbose_name="id of visit", on_delete=models.CASCADE) state = models.IntegerField(verbose_name="type of photo", choices=IMAGE_STATES) comment = models.TextField(verbose_name="comment on the photo") diff --git a/backend/drtrottoir/tests/factories/photo_factory.py b/backend/drtrottoir/tests/factories/photo_factory.py index 43eadfc8..01bc1de8 100644 --- a/backend/drtrottoir/tests/factories/photo_factory.py +++ b/backend/drtrottoir/tests/factories/photo_factory.py @@ -7,6 +7,7 @@ class PhotoFactory(DjangoModelFactory): + image = factory.Faker("image_url") visit = factory.SubFactory(VisitFactory) state = random.choice([0, 1, 2]) comment = factory.Faker("sentence") diff --git a/backend/drtrottoir/tests/factories/visit_factory.py b/backend/drtrottoir/tests/factories/visit_factory.py index bd086aa7..d7bbcefd 100644 --- a/backend/drtrottoir/tests/factories/visit_factory.py +++ b/backend/drtrottoir/tests/factories/visit_factory.py @@ -1,4 +1,3 @@ -from django.utils import timezone from factory.django import DjangoModelFactory import factory from django.utils import timezone diff --git a/backend/drtrottoir/tests/views/test_photo.py b/backend/drtrottoir/tests/views/test_photo.py index 19b53cec..775c2642 100644 --- a/backend/drtrottoir/tests/views/test_photo.py +++ b/backend/drtrottoir/tests/views/test_photo.py @@ -37,12 +37,12 @@ def test_delete_fault(self): def test_patch(self): response1 = self.client.patch( '/api/photo/' + str(self.photo.pk) + "/", + content_type="application/x-www-form-urlencoded", data={"comment": "nieuwe zin"}, follow=True ) + response2 = self.client.get(reverse("photo-detail", kwargs={'pk': self.photo.pk})) self.assertNotEqual(response1.data, self.photo) self.assertEqual(response1.data["comment"], response2.data["comment"]) - - diff --git a/backend/drtrottoir/views/photo_viewset.py b/backend/drtrottoir/views/photo_viewset.py index d23d16f4..cd30e531 100644 --- a/backend/drtrottoir/views/photo_viewset.py +++ b/backend/drtrottoir/views/photo_viewset.py @@ -3,6 +3,7 @@ from drtrottoir.models import Photo from drtrottoir.permissions.user_permissions import SuperPermissionOrReadOnly from drtrottoir.serializers import PhotoSerializer +from rest_framework.parsers import MultiPartParser, FormParser class PhotoViewSet(viewsets.ModelViewSet): @@ -12,4 +13,5 @@ class PhotoViewSet(viewsets.ModelViewSet): queryset = Photo.objects.all() serializer_class = PhotoSerializer + parser_classes = (MultiPartParser, FormParser) permission_classes = [IsAuthenticated & SuperPermissionOrReadOnly] diff --git a/backend/fixtures/init_data.json b/backend/fixtures/init_data.json index 5e2bfa18..525279c9 100644 --- a/backend/fixtures/init_data.json +++ b/backend/fixtures/init_data.json @@ -125,15 +125,6 @@ "user": 2, "comment": "Vuilbakken zijn buitengezet" } -}, -{ - "model": "drtrottoir.photo", - "pk": 1, - "fields": { - "visit": 1, - "state": "1", - "comment": "Alles gelukt", - "created_at": "2023-03-08T16:00:33Z" - } } + ] diff --git a/backend/requirements.txt b/backend/requirements.txt index 328a06bb..c2dcc3be 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -11,4 +11,5 @@ Faker==17.6.0 factory-boy==3.2.1 flake8==6.0.0 coverage==7.2.1 -django-nose==1.4.7 \ No newline at end of file +django-nose==1.4.7 +pillow==9.4.0 \ No newline at end of file diff --git a/backend/test_file.py b/backend/test_file.py deleted file mode 100644 index e69de29b..00000000 From 0f7299ab4cbd2afaf951bcb2f0dbc5b5825aa3dd Mon Sep 17 00:00:00 2001 From: milachae Date: Thu, 16 Mar 2023 00:07:19 +0100 Subject: [PATCH 08/12] added migrations --- .../migrations/0010_alter_photo_visit.py | 19 +++++++++++++++++++ .../drtrottoir/migrations/0011_photo_image.py | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 backend/drtrottoir/migrations/0010_alter_photo_visit.py create mode 100644 backend/drtrottoir/migrations/0011_photo_image.py diff --git a/backend/drtrottoir/migrations/0010_alter_photo_visit.py b/backend/drtrottoir/migrations/0010_alter_photo_visit.py new file mode 100644 index 00000000..89eebbe0 --- /dev/null +++ b/backend/drtrottoir/migrations/0010_alter_photo_visit.py @@ -0,0 +1,19 @@ +# Generated by Django 4.1.7 on 2023-03-15 20:08 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('drtrottoir', '0009_alter_customuser_buildings_alter_customuser_region'), + ] + + operations = [ + migrations.AlterField( + model_name='photo', + name='visit', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='drtrottoir.visit', verbose_name='id of visit'), + ), + ] diff --git a/backend/drtrottoir/migrations/0011_photo_image.py b/backend/drtrottoir/migrations/0011_photo_image.py new file mode 100644 index 00000000..16a9ffae --- /dev/null +++ b/backend/drtrottoir/migrations/0011_photo_image.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.7 on 2023-03-15 20:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('drtrottoir', '0010_alter_photo_visit'), + ] + + operations = [ + migrations.AddField( + model_name='photo', + name='image', + field=models.ImageField(null=True, upload_to='images/', verbose_name='image'), + ), + ] From c625c1880667c08a30f44ddeb963a61f8ca2400d Mon Sep 17 00:00:00 2001 From: milachae Date: Thu, 16 Mar 2023 13:50:18 +0100 Subject: [PATCH 09/12] #64: Delete images on DELETE --- backend/drtrottoir/models/photo.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/backend/drtrottoir/models/photo.py b/backend/drtrottoir/models/photo.py index a38fc0e5..2e3e7ca6 100644 --- a/backend/drtrottoir/models/photo.py +++ b/backend/drtrottoir/models/photo.py @@ -1,6 +1,7 @@ from django.db import models - from .visit import Visit +from django.dispatch import receiver +from django.db.models.signals import pre_delete IMAGE_STATES = ((1, 'Arrival'), (2, 'Departure'), (3, 'Extra')) @@ -14,3 +15,9 @@ class Photo(models.Model): def __str__(self): return f"{self.visit}, {self.created_at}" + + +@receiver(pre_delete, sender=Photo) +def pre_delete(sender, instance: Photo, **kwargs): + instance.image.delete() + From 061edd85f6aaabdf284d619f0919f9ba3712eec4 Mon Sep 17 00:00:00 2001 From: milachae Date: Thu, 16 Mar 2023 19:02:07 +0100 Subject: [PATCH 10/12] photos available to visit --- backend/drtrottoir/views/visit_viewset.py | 24 ++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/backend/drtrottoir/views/visit_viewset.py b/backend/drtrottoir/views/visit_viewset.py index 3756b130..c3fb9cb3 100644 --- a/backend/drtrottoir/views/visit_viewset.py +++ b/backend/drtrottoir/views/visit_viewset.py @@ -1,8 +1,14 @@ -from rest_framework import viewsets +from django.urls import reverse +from rest_framework import viewsets, status, serializers +from rest_framework.decorators import action from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response + from drtrottoir.models import Visit from drtrottoir.permissions.user_permissions import SuperPermissionOrReadOnly from drtrottoir.serializers import VisitSerializer +from drtrottoir.models import Photo, Building +from drtrottoir.serializers import PhotoSerializer class VisitViewSet(viewsets.ModelViewSet): @@ -29,3 +35,19 @@ class VisitViewSet(viewsets.ModelViewSet): queryset = Visit.objects.all() serializer_class = VisitSerializer permission_classes = [IsAuthenticated & SuperPermissionOrReadOnly] + + @action(detail=True, methods=['get']) + def photos(self, request, pk=None): + """ + Get all photos inside a visit. Authentication required. + """ + if pk is not None and Visit.objects.filter(pk=pk).exists(): + + urls = [] + for photo in Photo.objects.filter(visit=pk): + url = reverse('photo-detail', args=[photo.id]) + urls.append(request.build_absolute_uri(url)) + + return Response({"photos": urls}) + else: + return Response("Given visit doesn't exist.", status=status.HTTP_400_BAD_REQUEST) From eb94085e11ed36d3e684c5f17660d69292752e7b Mon Sep 17 00:00:00 2001 From: milachae Date: Thu, 16 Mar 2023 19:24:23 +0100 Subject: [PATCH 11/12] fix linter issues --- backend/drtrottoir/models/photo.py | 1 - backend/drtrottoir/views/visit_viewset.py | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/backend/drtrottoir/models/photo.py b/backend/drtrottoir/models/photo.py index 2e3e7ca6..2c429974 100644 --- a/backend/drtrottoir/models/photo.py +++ b/backend/drtrottoir/models/photo.py @@ -20,4 +20,3 @@ def __str__(self): @receiver(pre_delete, sender=Photo) def pre_delete(sender, instance: Photo, **kwargs): instance.image.delete() - diff --git a/backend/drtrottoir/views/visit_viewset.py b/backend/drtrottoir/views/visit_viewset.py index c3fb9cb3..e67b062b 100644 --- a/backend/drtrottoir/views/visit_viewset.py +++ b/backend/drtrottoir/views/visit_viewset.py @@ -1,14 +1,13 @@ from django.urls import reverse -from rest_framework import viewsets, status, serializers +from rest_framework import viewsets, status from rest_framework.decorators import action from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response +from drtrottoir.models import Photo from drtrottoir.models import Visit from drtrottoir.permissions.user_permissions import SuperPermissionOrReadOnly from drtrottoir.serializers import VisitSerializer -from drtrottoir.models import Photo, Building -from drtrottoir.serializers import PhotoSerializer class VisitViewSet(viewsets.ModelViewSet): From 8cb1a6a4994627b9dac2f3d21fd9019eeef34640 Mon Sep 17 00:00:00 2001 From: milachae Date: Thu, 16 Mar 2023 20:34:11 +0100 Subject: [PATCH 12/12] added migration --- ...r_photo_visit.py => 0014_photo_image_alter_photo_visit.py} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename backend/drtrottoir/migrations/{0013_photo_image_alter_photo_visit.py => 0014_photo_image_alter_photo_visit.py} (84%) diff --git a/backend/drtrottoir/migrations/0013_photo_image_alter_photo_visit.py b/backend/drtrottoir/migrations/0014_photo_image_alter_photo_visit.py similarity index 84% rename from backend/drtrottoir/migrations/0013_photo_image_alter_photo_visit.py rename to backend/drtrottoir/migrations/0014_photo_image_alter_photo_visit.py index d128b6e4..76f60284 100644 --- a/backend/drtrottoir/migrations/0013_photo_image_alter_photo_visit.py +++ b/backend/drtrottoir/migrations/0014_photo_image_alter_photo_visit.py @@ -1,4 +1,4 @@ -# Generated by Django 4.1.7 on 2023-03-16 17:09 +# Generated by Django 4.1.7 on 2023-03-16 19:31 from django.db import migrations, models import django.db.models.deletion @@ -6,7 +6,7 @@ class Migration(migrations.Migration): dependencies = [ - ("drtrottoir", "0012_alter_waste_building"), + ("drtrottoir", "0013_remove_visit_building_visit_building_in_tour"), ] operations = [