0
0
mirror of https://github.com/wagtail/wagtail.git synced 2024-12-01 11:41:20 +01:00

Make cross-link URLs on generic model views optional

Normally, generic model views will be spun up through wagtail.admin.viewsets, which takes care of configuring the add_url_name / edit_url_name etc attributes to ensure that they are cross-linked appropriately. But if you're defining one in isolation, that's an unnecessary hoop to jump through, and the error messages if you don't specify them are fairly opaque. Fix this so that:

1. Non-essential cross-links (e.g. the Add button on the index view, and the Delete button on the edit view) are gracefully omitted if the URLs are undefined;
2. Essential cross-links (e.g. the destination of the redirect after a successful form submission) raise an informative error telling the developer what needs to be defined.
This commit is contained in:
Matt Westcott 2021-10-26 23:36:41 +01:00 committed by LB (Ben Johnston)
parent 55fdafdfe6
commit 45ac80bb89
5 changed files with 50 additions and 7 deletions

View File

@ -15,6 +15,7 @@ Changelog
* Add informational Codecov status checks for GitHub CI pipelines (Tom Hu)
* Replace `PageRevision` with generic `Revision` model (Sage Abdullah)
* Make it possible to reuse and customise Wagtails fonts with CSS variables (LB (Ben) Johnston)
* Add better handling and informative developer errors for cross linking URLS (e.g. success after add) in generic views `wagtail.admin.views.generic` (Matt Westcott)
* Fix: Typo in `ResumeWorkflowActionFormatter` message (Stefan Hammer)
* Fix: Throw a meaningful error when saving an image to an unrecognised image format (Christian Franke)
* Fix: Remove extra padding for headers with breadcrumbs on mobile viewport (Steven Steinwand)

View File

@ -20,6 +20,7 @@ depth: 1
* Use `FormData` instead of jQuery's `form.serialize` when editing documents or images just added so that additional fields can be better supported (Stefan Hammer)
* Add informational Codecov status checks for GitHub CI pipelines (Tom Hu)
* Make it possible to reuse and customise Wagtails fonts with CSS variables (LB (Ben) Johnston)
* Add better handling and informative developer errors for cross linking URLS (e.g. success after add) in generic views `wagtail.admin.views.generic` (Matt Westcott)
### Bug fixes

View File

@ -3,7 +3,7 @@
{% block actions %}
<input type="submit" value="{% trans 'Save' %}" class="button" />
{% if can_delete %}
{% if delete_url %}
<a href="{{ delete_url }}" class="button button-secondary no">{{ delete_item_label }}</a>
{% endif %}
{% endblock %}

View File

@ -4,9 +4,8 @@
{% block titletag %}{{ page_title }} {{ page_subtitle }}{% endblock %}
{% block content %}
{% if can_add %}
{% url view.add_url_name as add_link %}
{% include "wagtailadmin/shared/header.html" with title=page_title subtitle=page_subtitle action_url=add_link action_text=view.add_item_label icon=header_icon only %}
{% if add_url %}
{% include "wagtailadmin/shared/header.html" with title=page_title subtitle=page_subtitle action_url=add_url action_text=add_item_label icon=header_icon only %}
{% else %}
{% include "wagtailadmin/shared/header.html" with title=page_title subtitle=page_subtitle icon=header_icon only %}
{% endif %}

View File

@ -1,4 +1,5 @@
from django import VERSION as DJANGO_VERSION
from django.core.exceptions import ImproperlyConfigured
from django.db import transaction
from django.forms import Form
from django.http import HttpResponseRedirect
@ -62,6 +63,7 @@ class IndexView(
model = None
index_url_name = None
add_url_name = None
add_item_label = _("Add")
edit_url_name = None
template_name = "wagtailadmin/generic/index.html"
context_object_name = None
@ -141,6 +143,10 @@ class IndexView(
if self.edit_url_name:
return reverse(self.edit_url_name, args=(instance.pk,))
def get_add_url(self):
if self.add_url_name:
return reverse(self.add_url_name)
def get_valid_orderings(self):
orderings = []
for col in self.columns:
@ -169,6 +175,10 @@ class IndexView(
self.permission_policy is None
or self.permission_policy.user_has_permission(self.request.user, "add")
)
if context["can_add"]:
context["add_url"] = self.get_add_url()
context["add_item_label"] = self.add_item_label
context["table"] = table
context["media"] = table.media
context["index_url"] = index_url
@ -201,9 +211,19 @@ class CreateView(
submit_button_label = gettext_lazy("Create")
def get_add_url(self):
if not self.add_url_name:
raise ImproperlyConfigured(
"Subclasses of wagtail.admin.views.generic.models.CreateView must provide an "
"add_url_name attribute or a get_add_url method"
)
return reverse(self.add_url_name)
def get_success_url(self):
if not self.index_url_name:
raise ImproperlyConfigured(
"Subclasses of wagtail.admin.views.generic.models.CreateView must provide an "
"index_url_name attribute or a get_success_url method"
)
return reverse(self.index_url_name)
def get_success_message(self, instance):
@ -289,12 +309,23 @@ class EditView(
return str(self.object)
def get_edit_url(self):
if not self.edit_url_name:
raise ImproperlyConfigured(
"Subclasses of wagtail.admin.views.generic.models.EditView must provide an "
"edit_url_name attribute or a get_edit_url method"
)
return reverse(self.edit_url_name, args=(self.object.id,))
def get_delete_url(self):
return reverse(self.delete_url_name, args=(self.object.id,))
if self.delete_url_name:
return reverse(self.delete_url_name, args=(self.object.id,))
def get_success_url(self):
if not self.index_url_name:
raise ImproperlyConfigured(
"Subclasses of wagtail.admin.views.generic.models.EditView must provide an "
"index_url_name attribute or a get_success_url method"
)
return reverse(self.index_url_name)
def save_instance(self):
@ -350,12 +381,13 @@ class EditView(
context = super().get_context_data(**kwargs)
context["action_url"] = self.get_edit_url()
context["submit_button_label"] = self.submit_button_label
context["delete_url"] = self.get_delete_url()
context["delete_item_label"] = self.delete_item_label
context["can_delete"] = (
self.permission_policy is None
or self.permission_policy.user_has_permission(self.request.user, "delete")
)
if context["can_delete"]:
context["delete_url"] = self.get_delete_url()
context["delete_item_label"] = self.delete_item_label
return context
@ -381,12 +413,22 @@ class DeleteView(
return super().get_object(queryset)
def get_success_url(self):
if not self.index_url_name:
raise ImproperlyConfigured(
"Subclasses of wagtail.admin.views.generic.models.DeleteView must provide an "
"index_url_name attribute or a get_success_url method"
)
return reverse(self.index_url_name)
def get_page_subtitle(self):
return str(self.object)
def get_delete_url(self):
if not self.index_url_name:
raise ImproperlyConfigured(
"Subclasses of wagtail.admin.views.generic.models.DeleteView must provide a "
"delete_url_name attribute or a get_delete_url method"
)
return reverse(self.delete_url_name, args=(self.object.id,))
def get_success_message(self):