diff --git a/gallery/admin.py b/gallery/admin.py index 8c38f3f..8d97081 100644 --- a/gallery/admin.py +++ b/gallery/admin.py @@ -1,3 +1,5 @@ -from django.contrib import admin +from urlaubsauktion.admin import joker_admin as admin -# Register your models here. +from .models import Image + +admin.register(Image) \ No newline at end of file diff --git a/gallery/helpers.py b/gallery/helpers.py new file mode 100644 index 0000000..665e792 --- /dev/null +++ b/gallery/helpers.py @@ -0,0 +1,4 @@ +from django.conf import settings + +def get_upload_path(instance, filename): + return instance.upload_path or settings.GALLERY_UPLOAD_PATH \ No newline at end of file diff --git a/gallery/mixins.py b/gallery/mixins.py new file mode 100644 index 0000000..b1867eb --- /dev/null +++ b/gallery/mixins.py @@ -0,0 +1,13 @@ +from django.contrib.contenttypes.fields import GenericRelation +from django.db import models + +from .models import Image + +class GalleryMixin(models.Model): + image_set = GenericRelation(Image) + + def add_image(self, image, upload_path=None): + Image.objects.create(image=image, content_object=self, upload_path=upload_path) + + class Meta: + abstract = True \ No newline at end of file diff --git a/gallery/models.py b/gallery/models.py index 71a8362..87f12e1 100644 --- a/gallery/models.py +++ b/gallery/models.py @@ -1,3 +1,20 @@ from django.db import models +from django.contrib.contenttypes.fields import GenericForeignKey +from django.contrib.contenttypes.models import ContentType -# Create your models here. +from .helpers import get_upload_path + +class Image(models.Model): + image = models.ImageField(upload_to=get_upload_path) + title = models.CharField(max_length=128, null=True, blank=True) + comment = models.TextField(null=True, blank=True) + + content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) + object_id = models.PositiveIntegerField() + content_object = GenericForeignKey('content_type', 'object_id') + + upload_path = models.CharField(max_length=256, null=True, blank=True) + + @property + def url(self): + return self.image.url \ No newline at end of file diff --git a/partners/models.py b/partners/models.py index a7a2083..deb084c 100644 --- a/partners/models.py +++ b/partners/models.py @@ -3,6 +3,7 @@ from django.contrib.gis.db import models from .features import * from localauth.models import User, Profile, LocationMixin, ImageMixin, PhoneMixin +from gallery.mixins import GalleryMixin from django_countries.fields import CountryField @@ -11,7 +12,7 @@ class PartnerProfile(Profile): def roomcategory_set(self): return RoomCategory.objects.filter(establishment__in=self.establishment_set.all()) -class Establishment(LocationMixin, ImageMixin, PhoneMixin): +class Establishment(LocationMixin, ImageMixin, PhoneMixin, GalleryMixin): owner = models.ForeignKey(PartnerProfile, models.CASCADE) name = models.CharField("Name", max_length=64) stars = models.IntegerField("Sterne", null=True, blank=True) @@ -40,7 +41,7 @@ class Establishment(LocationMixin, ImageMixin, PhoneMixin): return querysets[0].union(*querysets[1:]) -class RoomCategory(ImageMixin): +class RoomCategory(GalleryMixin): establishment = models.ForeignKey(Establishment, models.CASCADE) name = models.CharField("Name", max_length=64) average_price = models.DecimalField("Durchschnittspreis / Nacht", max_digits=10, decimal_places=2) diff --git a/partners/urls.py b/partners/urls.py index 27dc31d..e6d9e9d 100644 --- a/partners/urls.py +++ b/partners/urls.py @@ -1,7 +1,7 @@ from django.urls import path, reverse_lazy from django.views.generic import RedirectView -from .views import PartnerRegistrationView, PartnerProfileView, OffersListView, EstablishmentsListView, EstablishmentRequestView, PartnerDashboardView, EstablishmentVerificationView, RoomCategoryListView +from .views import PartnerRegistrationView, PartnerProfileView, OffersListView, EstablishmentsListView, EstablishmentRequestView, PartnerDashboardView, EstablishmentVerificationView, RoomCategoryListView, EstablishmentGalleryManagementView app_name = "partners" @@ -10,6 +10,7 @@ urlpatterns = [ path('profile/', PartnerProfileView.as_view(), name="profile"), path('establishments/', EstablishmentsListView.as_view(), name="establishments"), path('establishments//', RoomCategoryListView.as_view(), name="roomcategories"), + path('establishments//gallery/', EstablishmentGalleryManagementView.as_view(), name="establishment_gallery"), path('establishments/validate/', EstablishmentVerificationView.as_view(), name="establishment_verify"), path('establishments/register/', EstablishmentRequestView.as_view(), name="establishment_register"), path('offers/', OffersListView.as_view(), name="offers"), diff --git a/partners/views.py b/partners/views.py index edbcf66..54f5dc2 100644 --- a/partners/views.py +++ b/partners/views.py @@ -11,6 +11,7 @@ from .forms import VerificationForm from auction.models import Inquiry, Offer from public.mixins import InConstructionMixin from localauth.mixins import LoginRequiredMixin, SuperUserRequiredMixin +from gallery.models import Image class PartnerRegistrationView(InConstructionMixin, LoginRequiredMixin, CreateView): model = PartnerProfile @@ -152,4 +153,49 @@ class EstablishmentVerificationView(SuperUserRequiredMixin, FormView): messages.success(self.request, "Unterkunft %s bestätigt!" % eobj[0].name) - return HttpResponseRedirect(reverse_lazy("partners:establishment_verify")) \ No newline at end of file + return HttpResponseRedirect(reverse_lazy("partners:establishment_verify")) + +class EstablishmentGalleryManagementView(PartnerProfileRequiredMixin, CreateView, ListView): + model = Image + template_name = "partners/establishment_gallery_manage.html" + fields = ["image", "title", "comment"] + + def dispatch(self, request, *args, **kwargs): + self.establishment = self.get_establishment() + self.object_list = self.get_queryset() + + if not self.establishment: + return redirect("partners:establishment_register") + + return super().dispatch(request, *args, **kwargs) + + def get_establishment(self): + establishment = self.kwargs.get("id", None) + kwargs = {"owner": self.request.user.partnerprofile} + + if establishment: + kwargs["id"] = establishment + return get_object_or_404(Establishment, **kwargs) + else: + return Establishment.objects.filter(**kwargs).first() + + def get_queryset(self): + establishment = self.establishment + return establishment.image_set.all() + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["establishment"] = self.establishment + return context + + def form_valid(self, form): + form.instance.content_object = self.establishment + + for filename, file in self.request.FILES.items(): + name = self.request.FILES[filename].name + + form.instance.upload_path = f"userfiles/{self.request.user.id}/{name}" + return super().form_valid(form) + + def get_success_url(self): + return reverse_lazy("partners:establishment_gallery", args=[self.establishment.id]) \ No newline at end of file diff --git a/public/templatetags/splitter.py b/public/templatetags/splitter.py new file mode 100644 index 0000000..f7c9ff7 --- /dev/null +++ b/public/templatetags/splitter.py @@ -0,0 +1,7 @@ +from django import template + +register = template.Library() + +@register.simple_tag +def splitter(l, c=3): + return [l[i:i+c] for i in range(0, len(l), c)] \ No newline at end of file diff --git a/templates/partners/establishment_gallery_manage.html b/templates/partners/establishment_gallery_manage.html new file mode 100644 index 0000000..9cee17d --- /dev/null +++ b/templates/partners/establishment_gallery_manage.html @@ -0,0 +1,120 @@ +{% extends "partners/base.html" %} +{% load i18n %} +{% load bootstrap4 %} +{% load splitter %} +{% block "dashboardcontent" %} +
+

Deine Bilder

+
für {{ establishment.name }}
+ + + + + +
+{% endblock %} + +{% block "modal" %} + + + + +{% endblock %} \ No newline at end of file diff --git a/urlaubsauktion/settings.py b/urlaubsauktion/settings.py index 128cc56..c5ab804 100644 --- a/urlaubsauktion/settings.py +++ b/urlaubsauktion/settings.py @@ -133,4 +133,6 @@ STATICFILES_STORAGE = 'storages.backends.s3boto3.S3StaticStorage' if ENABLE_S3_S DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' -PHONENUMBER_DEFAULT_REGION = JOKER_COUNTRIES[0] \ No newline at end of file +PHONENUMBER_DEFAULT_REGION = JOKER_COUNTRIES[0] + +GALLERY_UPLOAD_PATH = "/userfiles/" \ No newline at end of file