From 05a33eb9161efde2b2b11cdc36e260c6a22fd605 Mon Sep 17 00:00:00 2001 From: Donald Buczek Date: Sun, 9 Feb 2025 12:23:56 +0100 Subject: [PATCH] personal: Change grous to ManyToManyField We want to split responsibilities for defining groups and assigning groups to position. Therefore we no longer want thegroupspositions inline panel in the contact model admin. Make groups into a simple ManyToMany field. Add sql code to autogenerated migration to transfer data from the old through table "personal_contactgroups" to the new one ("personal_contact_groups"). Adapt queries. --- .../migrations/0030_auto_20250209_1143.py | 22 ++++++++++++++++ mpicms/personal/models.py | 25 +++---------------- mpicms/personal/views.py | 2 +- mpicms/personal/wagtail_hooks.py | 4 +-- mpicms/templates/personal/list.html | 2 +- 5 files changed, 29 insertions(+), 26 deletions(-) create mode 100644 mpicms/personal/migrations/0030_auto_20250209_1143.py diff --git a/mpicms/personal/migrations/0030_auto_20250209_1143.py b/mpicms/personal/migrations/0030_auto_20250209_1143.py new file mode 100644 index 0000000..85f6c1a --- /dev/null +++ b/mpicms/personal/migrations/0030_auto_20250209_1143.py @@ -0,0 +1,22 @@ +# Generated by Django 3.1.7 on 2025-02-09 10:43 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('personal', '0029_auto_20250209_1010'), + ] + + operations = [ + migrations.AddField( + model_name='contact', + name='groups', + field=models.ManyToManyField(blank=True, related_name='contacts', to='personal.Group', verbose_name='groups'), + ), + migrations.RunSQL("INSERT INTO personal_contact_groups(id, contact_id, group_id) SELECT id, contact_id, group_id FROM personal_contactgroups"), + migrations.DeleteModel( + name='ContactGroups', + ), + ] diff --git a/mpicms/personal/models.py b/mpicms/personal/models.py index d43cab3..1875852 100644 --- a/mpicms/personal/models.py +++ b/mpicms/personal/models.py @@ -12,30 +12,12 @@ from modelcluster.fields import ParentalKey +# still used in migrations class FilterableParentalKey(ParentalKey): def get_related_field(self): return self.remote_field -class ContactGroups(Orderable, models.Model): - """ - This defines the relationship between the `Group` within the `Contact` model below. - """ - contact = FilterableParentalKey( - 'Contact', related_name=_('groups'), on_delete=models.CASCADE - ) - group = models.ForeignKey( - 'personal.Group', - related_name='contacts', - on_delete=models.CASCADE, - verbose_name=_('group') - ) - - panels = [ - SnippetChooserPanel('group'), - ] - - class ContactManager(models.Manager): def get_queryset(self): return super().get_queryset().filter(is_active=True) @@ -146,6 +128,7 @@ class Contact(index.Indexed, ClusterableModel): status = models.ForeignKey(Status, on_delete=models.SET_NULL, blank=True, null=True) special_functions = models.ManyToManyField(SpecialFunction, verbose_name=_('special functions'), blank=True) positions = models.ManyToManyField(Position, related_name="contacts", blank=True, verbose_name=_('positions')) + groups = models.ManyToManyField(Group, related_name="contacts", blank=True, verbose_name=_('groups')) objects = ContactManager() @@ -157,14 +140,12 @@ class Contact(index.Indexed, ClusterableModel): FieldPanel('academic_suffix'), ], heading='Name'), FieldPanel('status'), + FieldPanel('groups'), FieldPanel('positions'), FieldPanel('special_functions'), FieldPanel('email'), FieldPanel('phone'), FieldPanel('room'), - InlinePanel( - 'groups', label="Groups", - panels=None), FieldPanel('is_active'), FieldPanel('priority'), ] diff --git a/mpicms/personal/views.py b/mpicms/personal/views.py index 7306283..7f198da 100644 --- a/mpicms/personal/views.py +++ b/mpicms/personal/views.py @@ -13,7 +13,7 @@ def get_queryset(self): special_function_pk = self.request.GET.get('special_function') qs = super().get_queryset(); if group_pk is not None and group_pk != "": - qs = qs.filter(groups__group_id=group_pk) + qs = qs.filter(groups=group_pk) if position_pk is not None and position_pk != "": qs = qs.filter(positions=position_pk) diff --git a/mpicms/personal/wagtail_hooks.py b/mpicms/personal/wagtail_hooks.py index 5be9f1a..59df651 100644 --- a/mpicms/personal/wagtail_hooks.py +++ b/mpicms/personal/wagtail_hooks.py @@ -40,7 +40,7 @@ class ContactAdmin(ModelAdmin): menu_label = _('Persons') menu_icon = 'user' list_display = ['title', 'first_name', 'last_name', 'get_positions', 'email', 'phone', 'room', 'get_groups'] - list_filter = ['groups__group', 'is_active', 'positions'] + list_filter = ['groups', 'is_active', 'positions'] search_fields = ['title', 'first_name', 'last_name', 'email', 'phone', 'room'] edit_view_class = ContactEditView @@ -48,7 +48,7 @@ class ContactAdmin(ModelAdmin): delete_view_class = ContactDeleteView def get_groups(self, obj): - return ", ".join([group.__str__() for group in Group.objects.filter(contacts__in=obj.groups.all()).distinct()]) + return ", ".join([group.__str__() for group in obj.groups.all()]) get_groups.short_description = _('Groups') def get_positions(self, obj): diff --git a/mpicms/templates/personal/list.html b/mpicms/templates/personal/list.html index 5b691db..9df0ad9 100644 --- a/mpicms/templates/personal/list.html +++ b/mpicms/templates/personal/list.html @@ -109,7 +109,7 @@

{% trans 'Contact List' %}

{{ contact.email }} {{ contact.phone }} {{ contact.room | add_room_links }} - {% for contactgroup in contact.groups.all %}{{ contactgroup.group }}
{% endfor %} + {% for group in contact.groups.all %}{{ group }}
{% endfor %} {% for position in contact.positions.all %}{{ position }}
{% endfor %} {% for specialfunction in contact.special_functions.all %}{{ specialfunction.title }}
{% endfor %}