From 7148e8f449c88b8ea28e6748741a070cd692a3f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-S=C3=A9bastien=20Caux?= <git@jscaux.org> Date: Sat, 4 Feb 2023 10:47:08 +0100 Subject: [PATCH] Improve admin handling in forums --- scipost_django/forums/admin.py | 5 +- scipost_django/forums/forms.py | 15 ++ scipost_django/forums/models.py | 3 + .../forums/templates/forums/forum_detail.html | 8 +- scipost_django/forums/urls.py | 136 +++++++++++------- scipost_django/forums/views.py | 19 ++- 6 files changed, 119 insertions(+), 67 deletions(-) diff --git a/scipost_django/forums/admin.py b/scipost_django/forums/admin.py index 12b40e20e..844b114f2 100644 --- a/scipost_django/forums/admin.py +++ b/scipost_django/forums/admin.py @@ -16,13 +16,16 @@ class ForumAdmin(GuardedModelAdmin): "moderators", ] + def get_queryset(self, request): + return super().get_queryset(request).anchors() + admin.site.register(Forum, ForumAdmin) class MeetingAdmin(GuardedModelAdmin): prepopulated_fields = {"slug": ("name",)} - search_fields = ["name", "description", "preamble"] + search_fields = ["name", "description", "preamble", "minutes"] autocomplete_fields = [ "moderators", ] diff --git a/scipost_django/forums/forms.py b/scipost_django/forums/forms.py index c0b23e760..5ee198234 100644 --- a/scipost_django/forums/forms.py +++ b/scipost_django/forums/forms.py @@ -40,6 +40,8 @@ class ForumForm(forms.ModelForm): class MeetingForm(ForumForm): + parent = forms.ModelChoiceField(queryset=Forum.objects.anchors()) + class Meta: model = Meeting fields = [ @@ -50,11 +52,24 @@ class MeetingForm(ForumForm): "moderators", "parent_content_type", "parent_object_id", + "parent", "date_from", "date_until", "preamble", + "minutes", ] + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + if self.instance: + self.fields["parent"].initial = self.instance.parent + + def save(self): + meeting = super().save() + meeting.parent = self.cleaned_data["parent"] + meeting.save() + return meeting + class ForumGroupPermissionsForm(forms.ModelForm): """ diff --git a/scipost_django/forums/models.py b/scipost_django/forums/models.py index 33cc7ac95..850fbcee9 100644 --- a/scipost_django/forums/models.py +++ b/scipost_django/forums/models.py @@ -173,6 +173,9 @@ class Meeting(Forum): self.date_until.strftime("%Y-%m-%d"), ) + def get_absolute_url(self): + return reverse("forums:forum_detail", kwargs={"slug": self.slug}) + @property def future(self): return datetime.date.today() < self.date_from diff --git a/scipost_django/forums/templates/forums/forum_detail.html b/scipost_django/forums/templates/forums/forum_detail.html index 4fcf57f57..17c4614c5 100644 --- a/scipost_django/forums/templates/forums/forum_detail.html +++ b/scipost_django/forums/templates/forums/forum_detail.html @@ -46,7 +46,13 @@ <div class="container border border-danger m-2 p-2"> <h4>Admin actions:</h4> <ul> - <li><a href="{% url 'forums:forum_update' slug=forum.slug %}" class="text-warning">Update this {% if forum.meeting %}Meeting{% else %}Forum{% endif %}</a></li> + <li> + {% if forum.meeting %} + <a href="{% url 'forums:meeting_update' slug=forum.meeting.slug %}" class="text-warning">Update this Meeting</a> + {% else %} + <a href="{% url 'forums:forum_update' slug=forum.slug %}" class="text-warning">Update this Forum</a> + {% endif %} + </li> <li> {% if not forum.child_forums.all|length > 0 %} <a href="{% url 'forums:forum_delete' slug=forum.slug %}" class="text-danger">Delete this {% if forum.meeting %}Meeting{% else %}Forum{% endif %} (and all Posts {% if forum.meeting %}and Motions {% endif %}it contains)</a> diff --git a/scipost_django/forums/urls.py b/scipost_django/forums/urls.py index fbd05527c..190e78cc9 100644 --- a/scipost_django/forums/urls.py +++ b/scipost_django/forums/urls.py @@ -11,51 +11,105 @@ from . import views app_name = "forums" urlpatterns = [ + path("", views.ForumListView.as_view(), name="forums"), path( - "forum/<str:parent_model>/<int:parent_id>/add/", - views.ForumCreateView.as_view(), - name="forum_create", - ), - path("add/", views.ForumCreateView.as_view(), name="forum_create"), - path( - "meeting/<str:parent_model>/<int:parent_id>/add/", - views.MeetingCreateView.as_view(), - name="meeting_create", - ), - path("meeting/add/", views.MeetingCreateView.as_view(), name="meeting_create"), - path( - "<slug:slug>/", + "forum/", include([ path( - "", - views.ForumDetailView.as_view(), - name="forum_detail", + "<str:parent_model>/<int:parent_id>/add/", + views.ForumCreateView.as_view(), + name="forum_create", ), path( - "quicklinks/all", - views.HX_ForumQuickLinksAllView.as_view(), - name="_hx_forum_quick_links_all", + "<slug:slug>/update/", + views.ForumUpdateView.as_view(), + name="forum_update", ), + path("add/", views.ForumCreateView.as_view(), name="forum_create"), + ]), + ), + path( + "meeting/", + include([ path( - "quicklinks/followups", - views.HX_ForumQuickLinksFollowupsView.as_view(), - name="_hx_forum_quick_links_followups", + "<str:parent_model>/<int:parent_id>/add/", + views.MeetingCreateView.as_view(), + name="meeting_create", ), path( - "_hx_thread_from_post/<int:post_id>", - views._hx_thread_from_post, - name="_hx_thread_from_post", + "<slug:slug>/update/", + views.MeetingUpdateView.as_view(), + name="meeting_update", ), + path("add/", views.MeetingCreateView.as_view(), name="meeting_create"), + ]), + ), + path( + "<slug:slug>/", # from here on, forum and meeting + include([ path( - "update/", - views.ForumUpdateView.as_view(), - name="forum_update", + "", + views.ForumDetailView.as_view(), + name="forum_detail", ), path( "delete/", views.ForumDeleteView.as_view(), name="forum_delete", ), + path("motions/", + include([ + path( + "_hx_motion_form/", + include([ + path( + "button", + views._hx_motion_form_button, + name="_hx_motion_form_button", + ), + path( + "", + views._hx_motion_form, + name="_hx_motion_form", + ), + ]), + ), + path( + "<int:motion_id>/voting", + include([ + path( + "", + views._hx_motion_voting, + name="_hx_motion_voting", + ), + ]), + ), + ]), + ), + path("posts/", + include([ + path( + "_hx_thread_from_post/<int:post_id>", + views._hx_thread_from_post, + name="_hx_thread_from_post", + ), + ]), + ), + path( + "quicklinks/", + include([ + path( + "all", + views.HX_ForumQuickLinksAllView.as_view(), + name="_hx_forum_quick_links_all", + ), + path( + "followups", + views.HX_ForumQuickLinksFollowupsView.as_view(), + name="_hx_forum_quick_links_followups", + ), + ]), + ), path( "permissions/", include([ @@ -94,32 +148,6 @@ urlpatterns = [ ), ]), ), - path( - "_hx_motion_form/", - include([ - path( - "button", - views._hx_motion_form_button, - name="_hx_motion_form_button", - ), - path( - "", - views._hx_motion_form, - name="_hx_motion_form", - ), - ]), - ), - ]), - ), - path("", views.ForumListView.as_view(), name="forums"), - path( - "<slug:slug>/motion/<int:motion_id>/", - include([ - path( - "", - views._hx_motion_voting, - name="_hx_motion_voting", - ), ]), ), ] diff --git a/scipost_django/forums/views.py b/scipost_django/forums/views.py index 95c586ec2..dc34a8d0b 100644 --- a/scipost_django/forums/views.py +++ b/scipost_django/forums/views.py @@ -57,15 +57,18 @@ class ForumCreateView(PermissionsMixin, CreateView): parent_model = self.kwargs.get("parent_model") parent_content_type = None parent_object_id = self.kwargs.get("parent_id") + parent = None if parent_model == "forum": parent_content_type = ContentType.objects.get( app_label="forums", model="forum" ) + parent = get_object_or_404(Forum, pk=parent_object_id) initial.update( { "moderators": self.request.user, "parent_content_type": parent_content_type, "parent_object_id": parent_object_id, + "parent": parent, } ) return initial @@ -78,20 +81,14 @@ class MeetingCreateView(ForumCreateView): class ForumUpdateView(PermissionRequiredMixin, UpdateView): permission_required = "forums.update_forum" + model = Forum + form_class = ForumForm template_name = "forums/forum_form.html" - def get_object(self, queryset=None): - try: - return Meeting.objects.get(slug=self.kwargs["slug"]) - except Meeting.DoesNotExist: - return Forum.objects.get(slug=self.kwargs["slug"]) - def get_form(self, form_class=None): - try: - self.object.meeting - return MeetingForm(**self.get_form_kwargs()) - except Meeting.DoesNotExist: - return ForumForm(**self.get_form_kwargs()) +class MeetingUpdateView(ForumUpdateView): + model = Meeting + form_class = MeetingForm class ForumDeleteView(PermissionRequiredMixin, DeleteView): -- GitLab