From aa4ac4f1a8b8509f316b7bd0c7590f7c232388f0 Mon Sep 17 00:00:00 2001 From: Gunvor4 Date: Fri, 18 Aug 2023 10:36:52 +0200 Subject: [PATCH 01/31] Created new model Lore Created Lore model, modified save() method to always slugify title, set up compression of images, and added new model to Django admin --- src/internal/admin.py | 8 ++++++- src/internal/migrations/0027_lore.py | 30 +++++++++++++++++++++++++ src/internal/models.py | 33 +++++++++++++++++++++++++++- 3 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 src/internal/migrations/0027_lore.py diff --git a/src/internal/admin.py b/src/internal/admin.py index ef5c45fcf..0c70db9d5 100644 --- a/src/internal/admin.py +++ b/src/internal/admin.py @@ -5,7 +5,7 @@ from util import html_utils from util.admin_utils import DefaultAdminWidgetsMixin, UserSearchFieldsMixin, search_escaped_and_unescaped -from .models import Member, Quote, Secret, SystemAccess +from .models import Member, Quote, Secret, SystemAccess, Lore class MemberAdmin(DefaultAdminWidgetsMixin, SimpleHistoryAdmin): @@ -93,7 +93,13 @@ class QuoteAdmin(DefaultAdminWidgetsMixin, UserSearchFieldsMixin, admin.ModelAdm autocomplete_fields = ('author',) +class LoreAdmin(admin.ModelAdmin): + ordering = ('title',) + exclude = ('slug',) + + admin.site.register(Member, MemberAdmin) admin.site.register(SystemAccess, SystemAccessAdmin) admin.site.register(Secret, SecretAdmin) admin.site.register(Quote, QuoteAdmin) +admin.site.register(Lore, LoreAdmin) diff --git a/src/internal/migrations/0027_lore.py b/src/internal/migrations/0027_lore.py new file mode 100644 index 000000000..54b14cbd3 --- /dev/null +++ b/src/internal/migrations/0027_lore.py @@ -0,0 +1,30 @@ +# Generated by Django 4.1.7 on 2023-08-18 08:29 + +from django.db import migrations, models +import functools +import internal.models +import util.modelfields +import util.storage + + +class Migration(migrations.Migration): + + dependencies = [ + ('internal', '0026_add_secret_permissions'), + ] + + operations = [ + migrations.CreateModel( + name='Lore', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=50, verbose_name='title')), + ('slug', models.SlugField()), + ('text', models.TextField(verbose_name='text')), + ('image', util.modelfields.CompressedImageField(blank=True, max_length=200, storage=util.storage.OverwriteStorage(), upload_to=functools.partial(util.storage.UploadToUtils._actual_upload_to, *(), **{'upload_to': internal.models.internal_subclass_directory_path}), verbose_name='image')), + ], + options={ + 'verbose_name_plural': 'Lore articles', + }, + ), + ] diff --git a/src/internal/models.py b/src/internal/models.py index 02afa34cd..fafe81a29 100644 --- a/src/internal/models.py +++ b/src/internal/models.py @@ -5,7 +5,7 @@ from django.db.models import F from django.db.models.functions import Lower from django.utils import timezone -from django.utils.text import capfirst +from django.utils.text import capfirst, slugify from django.utils.translation import gettext_lazy as _ from phonenumber_field.modelfields import PhoneNumberField from phonenumber_field.phonenumber import PhoneNumber @@ -15,6 +15,8 @@ from groups.models import Committee from users.models import User from util.auth_utils import perm_to_str, perms_to_str +from util.modelfields import CompressedImageField +from util.storage import OverwriteStorage, UploadToUtils from util.url_utils import reverse_internal from web.modelfields import UnlimitedCharField from .modelfields import SemesterField @@ -314,3 +316,32 @@ class Meta: def __str__(self): return _("“{quote}” —{quoted}").format(quote=self.quote, quoted=self.quoted) + + +def internal_subclass_directory_path(instance: 'Lore', filename: str): + model_name = instance._meta.model_name + return f"internal/{model_name}s/{filename}" + + +class Lore(models.Model): + title = models.CharField(max_length=50, verbose_name=_("title"), null=False) + slug = models.SlugField() + text = models.TextField(verbose_name=_("text")) + image = CompressedImageField( + upload_to=UploadToUtils.get_pk_prefixed_filename_func(internal_subclass_directory_path), + max_length=200, + storage=OverwriteStorage(), + blank=True, + verbose_name=_("image") + ) + + def __str__(self): + return _("{title}").format(title=self.title) + + def save(self, *args, **kwargs): + self.slug = slugify(self.title) + super().save(*args, **kwargs) + + class Meta: + verbose_name_plural = 'Lore articles' + From 17d65c58dc29aa18ba2502440e084e926e006088 Mon Sep 17 00:00:00 2001 From: Gunvor4 Date: Fri, 18 Aug 2023 10:39:22 +0200 Subject: [PATCH 02/31] Made form for lore articles Made form to be used when adding or changing lore articles --- src/internal/forms.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/internal/forms.py b/src/internal/forms.py index 8918a8528..7431cc5d3 100644 --- a/src/internal/forms.py +++ b/src/internal/forms.py @@ -6,7 +6,7 @@ from card.formfields import CardNumberField from users.models import User from web.widgets import SemanticDateInput, SemanticMultipleSelectInput, SemanticSearchableChoiceInput -from .models import Member, Quote, Secret, SystemAccess +from .models import Member, Quote, Secret, SystemAccess, Lore class AddMemberForm(forms.ModelForm): @@ -176,3 +176,9 @@ class Meta: widgets = { 'date': SemanticDateInput(), } + + +class LoreForm(forms.ModelForm): + class Meta: + model = Lore + fields = ('title', 'text', 'image') From 612185f56bd8634303be7e3ecd2d7fcbc3bf5adc Mon Sep 17 00:00:00 2001 From: Gunvor4 Date: Fri, 18 Aug 2023 10:50:47 +0200 Subject: [PATCH 03/31] Added urls, views and template for lore wiki Added URLs and views for viewing the general lore article page and for viewing a particular lore article, for adding new lore article, and changing and deleting existing articles. Modified form_valid() method for the CreateView and the UpdateView, so the page throws an error if a user tries to write a new article on a topic that already exists. Added new template for viewing lore articles, and added lore wiki to the internal header. --- src/internal/templates/internal/header.html | 4 + .../templates/internal/lore_list.html | 63 ++++++++++++ src/internal/urls.py | 12 +++ src/internal/views.py | 99 ++++++++++++++++++- 4 files changed, 175 insertions(+), 3 deletions(-) create mode 100644 src/internal/templates/internal/lore_list.html diff --git a/src/internal/templates/internal/header.html b/src/internal/templates/internal/header.html index bcf274d8d..c278ca7b2 100644 --- a/src/internal/templates/internal/header.html +++ b/src/internal/templates/internal/header.html @@ -20,6 +20,10 @@
{% translate "Quotes" %}
+ +
{% translate "MAKE Lore" %}
+
+