diff --git a/README.md b/README.md index 52dccb3..9edddbc 100644 --- a/README.md +++ b/README.md @@ -79,8 +79,7 @@ production néccessite **une installation de Debian Bullseye ou plus récent**. ``` $ sudo apt install nginx git gettext uwsgi uwsgi-plugin-python3 python3-venv \ python3-certbot-nginx python3-django python3-django-crispy-forms \ - python3-django-taggit python3-pil python3-exifread python3-django-allauth \ - python3-psycopg2 python3-docutils + python3-pil python3-exifread python3-django-allauth python3-docutils ``` 2. **Clonage du dépot dans `/var/www/photos/photo21`** diff --git a/photologue/admin.py b/photologue/admin.py index ff797fb..f398fc7 100644 --- a/photologue/admin.py +++ b/photologue/admin.py @@ -1,4 +1,5 @@ from django.contrib import admin +from django.utils.translation import gettext_lazy as _ from .models import Gallery, Photo, Tag @@ -15,14 +16,19 @@ class GalleryAdmin(admin.ModelAdmin): class PhotoAdmin(admin.ModelAdmin): list_display = ('title', 'date_taken', 'date_added', - 'is_public', 'view_count', 'admin_thumbnail') - list_filter = ['date_added', 'is_public'] + 'is_public', 'view_count', 'admin_thumbnail', 'get_owner') + list_filter = ['date_added', 'is_public', 'owner'] search_fields = ['title', 'slug', 'caption'] list_per_page = 10 prepopulated_fields = {'slug': ('title',)} readonly_fields = ('date_taken',) model = Photo + def get_owner(self, obj): + return obj.owner.username + get_owner.admin_order_field = 'owner' + get_owner.short_description = _('owner') + class TagAdmin(admin.ModelAdmin): list_display = ('name',) @@ -30,4 +36,6 @@ class TagAdmin(admin.ModelAdmin): model = Tag +admin.site.register(Gallery, GalleryAdmin) +admin.site.register(Photo, PhotoAdmin) admin.site.register(Tag, TagAdmin) diff --git a/photologue/models.py b/photologue/models.py index 059ac44..8b94e5c 100644 --- a/photologue/models.py +++ b/photologue/models.py @@ -178,7 +178,7 @@ class Gallery(models.Model): verbose_name_plural = _('galleries') def __str__(self): - return self.title + return f"{ self.title } ({self.date_start})" def get_absolute_url(self): return reverse('photologue:pl-gallery', args=[self.slug]) diff --git a/photologue/views.py b/photologue/views.py index 93fc8b5..2741b50 100644 --- a/photologue/views.py +++ b/photologue/views.py @@ -7,7 +7,7 @@ from .models import Gallery, Photo class GalleryDateView(LoginRequiredMixin): queryset = Gallery.objects.filter(is_public=True) - date_field = 'extended__date_start' + date_field = 'date_start' uses_datetime_field = False # Fix related object access allow_empty = True diff --git a/photologue_custom/admin.py b/photologue_custom/admin.py deleted file mode 100644 index e8f0130..0000000 --- a/photologue_custom/admin.py +++ /dev/null @@ -1,47 +0,0 @@ -from django.contrib import admin -from django.utils.translation import gettext_lazy as _ -from photologue.admin import GalleryAdmin as GalleryAdminDefault -from photologue.admin import PhotoAdmin as PhotoAdminDefault -from photologue.models import Gallery, Photo - -from .models import GalleryExtended, PhotoExtended - - -class GalleryExtendedInline(admin.StackedInline): - model = GalleryExtended - can_delete = False - - -class GalleryAdmin(GalleryAdminDefault): - """ - Define our new one-to-one model as an inline of Photologue's Gallery - model. - """ - inlines = [GalleryExtendedInline, ] - - -class PhotoExtendedInline(admin.StackedInline): - model = PhotoExtended - can_delete = True - - -class PhotoAdmin(PhotoAdminDefault): - """ - Define our new one-to-one model as an inline of Photologue's Photo - model. - """ - inlines = [PhotoExtendedInline, ] - list_display = ('title', 'date_taken', 'date_added', - 'is_public', 'view_count', 'admin_thumbnail', 'get_owner') - list_filter = ['date_added', 'is_public', 'extended__owner'] - - def get_owner(self, obj): - if not hasattr(obj, 'extended'): - return "No owner" - return obj.extended.owner.username - get_owner.admin_order_field = 'owner' - get_owner.short_description = _('owner') - - -admin.site.register(Gallery, GalleryAdmin) -admin.site.register(Photo, PhotoAdmin) diff --git a/photologue_custom/forms.py b/photologue_custom/forms.py index 11a146d..96f4498 100644 --- a/photologue_custom/forms.py +++ b/photologue_custom/forms.py @@ -5,19 +5,7 @@ from crispy_forms.layout import Div, Layout, Submit from django import forms from django.utils.text import slugify from django.utils.translation import gettext_lazy as _ -from photologue.models import Gallery -from taggit.models import Tag - -from .models import GalleryExtended - - -class GalleryChoiceField(forms.ModelChoiceField): - def label_from_instance(self, obj): - """Show gallery event date.""" - if hasattr(obj, 'extended'): - return f"{ obj.title } ({obj.extended.date_start})" - else: - return obj.title +from photologue.models import Gallery, Tag class UploadForm(forms.Form): @@ -29,7 +17,7 @@ class UploadForm(forms.Form): 'class': 'mb-3', }), ) - gallery = GalleryChoiceField( + gallery = forms.ModelChoiceField( Gallery.objects.all(), label=_('Gallery'), required=False, @@ -100,12 +88,12 @@ class UploadForm(forms.Form): if not gallery: # Create new gallery title = self.cleaned_data.get('new_gallery_title') - gallery = Gallery.objects.create(title=title, slug=slugify(title)) - ext = GalleryExtended.objects.create( - gallery=gallery, + gallery = Gallery.objects.create( + title=title, + slug=slugify(title), date_start=self.cleaned_data['new_gallery_date_start'], date_end=self.cleaned_data['new_gallery_date_end'], ) for tag in self.cleaned_data['new_gallery_tags']: - ext.tags.add(tag) + gallery.tags.add(tag) return gallery diff --git a/photologue_custom/management/commands/rename_media.py b/photologue_custom/management/commands/rename_media.py index 62615e9..461870b 100644 --- a/photologue_custom/management/commands/rename_media.py +++ b/photologue_custom/management/commands/rename_media.py @@ -16,7 +16,7 @@ class Command(BaseCommand): media_dir = Path(settings.MEDIA_ROOT) for gallery in Gallery.objects.all(): # Create gallery directory - gallery_year = str(gallery.extended.date_start.year) + gallery_year = str(gallery.date_start.year) gallery_dir = Path('photos') / gallery_year / gallery.slug gallery_path = media_dir / gallery_dir if not gallery_path.exists(): diff --git a/photologue_custom/migrations/0005_auto_20220130_0953.py b/photologue_custom/migrations/0005_auto_20220130_0953.py new file mode 100644 index 0000000..ef769ec --- /dev/null +++ b/photologue_custom/migrations/0005_auto_20220130_0953.py @@ -0,0 +1,27 @@ +# Generated by Django 3.2.11 on 2022-01-30 09:53 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('photologue_custom', '0004_photoextended_license'), + ] + + operations = [ + migrations.RemoveField( + model_name='photoextended', + name='owner', + ), + migrations.RemoveField( + model_name='photoextended', + name='photo', + ), + migrations.DeleteModel( + name='GalleryExtended', + ), + migrations.DeleteModel( + name='PhotoExtended', + ), + ] diff --git a/photologue_custom/models.py b/photologue_custom/models.py deleted file mode 100644 index 6275e64..0000000 --- a/photologue_custom/models.py +++ /dev/null @@ -1,64 +0,0 @@ -from django.db import models -from django.conf import settings -from taggit.managers import TaggableManager -from photologue.models import Gallery, Photo -from django.utils.translation import gettext_lazy as _ - - -class GalleryExtended(models.Model): - # Extend Photologue Gallery model. - gallery = models.OneToOneField( - Gallery, - related_name='extended', - on_delete=models.CASCADE, - ) - - # Add tags - tags = TaggableManager(blank=True) - - # Add start and end dates fields to GalleryExtend - date_start = models.DateField( - blank=True, - null=True, - verbose_name=_("start date"), - ) - date_end = models.DateField( - blank=True, - null=True, - verbose_name=_("end date"), - ) - - class Meta: - verbose_name = 'Extra fields' - verbose_name_plural = 'Extra fields' - - def __str__(self): - return self.gallery.title - - -class PhotoExtended(models.Model): - # Extend Photologue Photo model. - photo = models.OneToOneField( - Photo, - related_name='extended', - on_delete=models.CASCADE, - ) - - # Add a owner field to PhotoExtended - owner = models.ForeignKey( - settings.AUTH_USER_MODEL, - on_delete=models.CASCADE, - verbose_name=_("owner"), - ) - license = models.CharField( - max_length=255, - blank=True, - verbose_name=_("license"), - ) - - class Meta: - verbose_name = 'Extra fields' - verbose_name_plural = 'Extra fields' - - def __str__(self): - return str(self.photo) diff --git a/photologue_custom/templates/photologue/gallery_detail.html b/photologue_custom/templates/photologue/gallery_detail.html index 9649dc7..1df68af 100644 --- a/photologue_custom/templates/photologue/gallery_detail.html +++ b/photologue_custom/templates/photologue/gallery_detail.html @@ -38,10 +38,10 @@ SPDX-License-Identifier: GPL-3.0-or-later {% endif %} -{% if gallery.extended.date_start %}

{{ gallery.extended.date_start }}{% if gallery.extended.date_end and gallery.extended.date_end != gallery.extended.date_start %} {% trans "to" %} {{ gallery.extended.date_end }}{% endif %}

{% endif %} -{% if gallery.extended.tags.all %} +{% if gallery.date_start %}

{{ gallery.date_start }}{% if gallery.date_end and gallery.date_end != gallery.date_start %} {% trans "to" %} {{ gallery.date_end }}{% endif %}

{% endif %} +{% if gallery.tags.all %}

- Tags : {% for tag in gallery.extended.tags.all %} + Tags : {% for tag in gallery.tags.all %} {{ tag }} {% endfor %}

@@ -70,7 +70,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% for photo in photos %} - {{ photo.title }}{% if photo.date_taken %} - {{ photo.date_taken|date }} {{ photo.date_taken|time }}{% endif %} - {{ photo.extended.owner.get_full_name }}{% if photo.extended.license %} - {{ photo.extended.license }}{% endif %} + {{ photo.title }}{% if photo.date_taken %} - {{ photo.date_taken|date }} {{ photo.date_taken|time }}{% endif %} - {{ photo.owner.get_full_name }}{% if photo.license %} - {{ photo.license }}{% endif %} {% endfor %}
diff --git a/photologue_custom/templates/photologue/includes/gallery_sample.html b/photologue_custom/templates/photologue/includes/gallery_sample.html index abe2bfd..8282074 100644 --- a/photologue_custom/templates/photologue/includes/gallery_sample.html +++ b/photologue_custom/templates/photologue/includes/gallery_sample.html @@ -6,7 +6,7 @@ {% endfor %}
{{ gallery.title }}
- {% if gallery.extended.date_start %}

{{ gallery.extended.date_start }}{% if gallery.extended.date_end and gallery.extended.date_end != gallery.extended.date_start %} - {{ gallery.extended.date_end }}{% endif %}

{% endif %} + {% if gallery.date_start %}

{{ gallery.date_start }}{% if gallery.date_end and gallery.date_end != gallery.date_start %} - {{ gallery.date_end }}{% endif %}

{% endif %}
diff --git a/photologue_custom/templates/taggit/tag_detail.html b/photologue_custom/templates/photologue/tag_detail.html similarity index 100% rename from photologue_custom/templates/taggit/tag_detail.html rename to photologue_custom/templates/photologue/tag_detail.html diff --git a/photologue_custom/views.py b/photologue_custom/views.py index 8a683f0..38ebc7f 100644 --- a/photologue_custom/views.py +++ b/photologue_custom/views.py @@ -16,12 +16,10 @@ from django.urls import reverse_lazy from django.utils.text import slugify from django.views.generic.detail import DetailView from django.views.generic.edit import FormView -from photologue.models import Gallery, Photo +from photologue.models import Gallery, Photo, Tag from PIL import Image -from taggit.models import Tag from .forms import UploadForm -from .models import PhotoExtended class TagDetail(LoginRequiredMixin, DetailView): @@ -34,8 +32,8 @@ class TagDetail(LoginRequiredMixin, DetailView): current_tag = self.get_object().slug context = super().get_context_data(**kwargs) context['galleries'] = Gallery.objects.filter(is_public=True) \ - .filter(extended__tags__slug=current_tag) \ - .order_by('-extended__date_start') + .filter(tags__slug=current_tag) \ + .order_by('-date_start') return context @@ -48,18 +46,18 @@ class CustomGalleryDetailView(LoginRequiredMixin, DetailView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - # Query with extended and owner to reduce database lag - context['photos'] = self.object.public().select_related('extended__owner') + # Query with owner to reduce database lag + context['photos'] = self.object.public().select_related('owner') # List owners context['owners'] = [] for photo in context['photos']: - if hasattr(photo, 'extended') and photo.extended.owner not in context['owners']: - context['owners'].append(photo.extended.owner) + if photo.owner not in context['owners']: + context['owners'].append(photo.owner) # Filter on owner if 'owner' in self.kwargs: - context['photos'] = context['photos'].filter(extended__owner__id=self.kwargs['owner']) + context['photos'] = context['photos'].filter(owner__id=self.kwargs['owner']) return context @@ -100,7 +98,7 @@ class GalleryUpload(PermissionRequiredMixin, FormView): # We take files from the request to support multiple upload files = self.request.FILES.getlist('file_field') gallery = form.get_or_create_gallery() - gallery_year = Path(str(gallery.extended.date_start.year)) + gallery_year = Path(str(gallery.date_start.year)) gallery_dir = gallery_year / gallery.slug failed_upload = 0 for photo_file in files: @@ -116,12 +114,15 @@ class GalleryUpload(PermissionRequiredMixin, FormView): title = f"{gallery.title} - {photo_file.name}" try: - photo = Photo(title=title, slug=slugify(title)) + photo = Photo( + title=title, + slug=slugify(title), + owner=self.request.user, + ) photo_name = str(gallery_dir / photo_file.name) photo.image.save(photo_name, photo_file) photo.save() photo.galleries.set([gallery]) - PhotoExtended.objects.create(photo=photo, owner=self.request.user) except IntegrityError: messages.error(self.request, f"{photo_file.name} was not uploaded. Maybe the photo was already uploaded.") failed_upload += 1 diff --git a/requirements.txt b/requirements.txt index 9f86e8d..cf9dcaf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,5 @@ django-allauth>=0.44 django-crispy-forms~=1.7 -django-taggit>=1.5.0 Django>=2.2.20 ExifRead>=2.1.2 git+https://gitlab.crans.org/bde/allauth-note-kfet.git