diff --git a/photologue/admin.py b/photologue/admin.py index 0c04abf..ff797fb 100644 --- a/photologue/admin.py +++ b/photologue/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin -from .models import Gallery, Photo +from .models import Gallery, Photo, Tag class GalleryAdmin(admin.ModelAdmin): @@ -9,7 +9,7 @@ class GalleryAdmin(admin.ModelAdmin): date_hierarchy = 'date_added' prepopulated_fields = {'slug': ('title',)} model = Gallery - autocomplete_fields = ['photos', ] + autocomplete_fields = ['photos', 'tags'] search_fields = ['title', ] @@ -22,3 +22,12 @@ class PhotoAdmin(admin.ModelAdmin): prepopulated_fields = {'slug': ('title',)} readonly_fields = ('date_taken',) model = Photo + + +class TagAdmin(admin.ModelAdmin): + list_display = ('name',) + search_fields = ('name',) + model = Tag + + +admin.site.register(Tag, TagAdmin) diff --git a/photologue/migrations/0014_merge_related.py b/photologue/migrations/0014_merge_related.py new file mode 100644 index 0000000..2608233 --- /dev/null +++ b/photologue/migrations/0014_merge_related.py @@ -0,0 +1,96 @@ +# Generated by Django 3.2.11 on 2022-01-30 08:32 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone +import taggit.managers +from django.contrib.auth.models import User +from django.contrib.contenttypes.models import ContentType +from django.template.defaultfilters import slugify + +numens = User.objects.get(username="Numens").id + +def migrate_related(apps, schema_editor): + Gallery = apps.get_model('photologue', 'Gallery') + Tag = apps.get_model('photologue', 'Tag') + TaggedItems = apps.get_model('taggit', 'TaggedItem') + ct_ext = ContentType.objects.get(app_label="photologue_custom", model="galleryextended") + for gallery in Gallery.objects.all(): + tagged_items = TaggedItems.objects.filter( + content_type_id=ct_ext.id, + object_id=gallery.extended.id + ) + tags = [tag.tag for tag in tagged_items.all()] + gallery.date_start = gallery.extended.date_start + gallery.date_end = gallery.extended.date_end + gallery.save() + for tag in tags: + try: + new_tag, created = Tag.objects.get_or_create( + name=tag.name.capitalize(), + slug=slugify(tag.name), + ) + if new_tag not in gallery.tags.all(): + gallery.tags.add(new_tag) + new_tag.save() + gallery.save() + except Exception: + continue + + Photo = apps.get_model('photologue', 'Photo') + for photo in Photo.objects.all(): + photo.owner = photo.extended.owner + photo.license = photo.extended.license + photo.save() + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('photologue', '0013_alter_gallery_photos'), + ] + + operations = [ + migrations.CreateModel( + name='Tag', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=250, unique=True, verbose_name='name')), + ('slug', models.SlugField(help_text='A "slug" is a unique URL-friendly title for an object.', max_length=250, unique=True, verbose_name='slug')), + ], + options={ + 'verbose_name': 'tag', + 'verbose_name_plural': 'tags', + 'ordering': ['name'], + }, + ), + migrations.AddField( + model_name='gallery', + name='date_end', + field=models.DateField(blank=True, null=True, verbose_name='end date'), + ), + migrations.AddField( + model_name='gallery', + name='date_start', + field=models.DateField(default=django.utils.timezone.now, verbose_name='start date'), + ), + migrations.AddField( + model_name='photo', + name='license', + field=models.CharField(blank=True, max_length=255, verbose_name='license'), + ), + migrations.AddField( + model_name='photo', + name='owner', + field=models.ForeignKey(default=numens, on_delete=django.db.models.deletion.CASCADE, to='auth.user', verbose_name='owner'), + preserve_default=False, + ), + migrations.AddField( + model_name='gallery', + name='tags', + field=models.ManyToManyField(blank=True, related_name='galleries', to='photologue.Tag', verbose_name='tags'), + ), + migrations.RunPython(migrate_related), + ] diff --git a/photologue/models.py b/photologue/models.py index f38fbc5..059ac44 100644 --- a/photologue/models.py +++ b/photologue/models.py @@ -145,8 +145,23 @@ class Gallery(models.Model): unique=True, max_length=250, help_text=_('A "slug" is a unique URL-friendly title for an object.')) + date_start = models.DateField( + default=now, + verbose_name=_("start date"), + ) + date_end = models.DateField( + blank=True, + null=True, + verbose_name=_("end date"), + ) description = models.TextField(_('description'), blank=True) + tags = models.ManyToManyField( + 'photologue.Tag', + related_name='galleries', + verbose_name=_('tags'), + blank=True, + ) is_public = models.BooleanField(_('is public'), default=True, help_text=_('Public galleries will be displayed ' @@ -478,6 +493,16 @@ class Photo(ImageModel): blank=True) date_added = models.DateTimeField(_('date added'), default=now) + 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"), + ) is_public = models.BooleanField(_('is public'), default=True, help_text=_('Public photographs will be displayed in the default views.')) @@ -657,3 +682,25 @@ def init_size_method_map(): {'base_name': '_get_size_url', 'size': size} size_method_map['get_%s_filename' % size] = \ {'base_name': '_get_size_filename', 'size': size} + + +class Tag(models.Model): + name = models.CharField( + max_length=250, + unique=True, + verbose_name=_('name'), + ) + slug = models.SlugField( + unique=True, + max_length=250, + verbose_name=_('slug'), + help_text=_('A "slug" is a unique URL-friendly title for an object.'), + ) + + class Meta: + ordering = ['name'] + verbose_name = _('tag') + verbose_name_plural = _('tags') + + def __str__(self): + return self.name