Django 5.1.5 (and other security releases released today) has added a `max_length` attribute to GenericIPAddressField, which breaks an assertion in the form builder tests that compares HTML directly. Change this to a BeautifulSoup-based test so that it works on older and newer releases.
Fixes#12688. Without this, commenting on a field of an ImageBlock will cause subsequent loads of the edit view to fail at the point that the comments validate that they are attached to a valid block path.
The get_usage() method returns a ReferenceGroups instance that defines a
__getitem__ method. Accessing get_usage().count() from the template
means that Django tries to access the count via ["count"], which fails,
then continues by using getattr(reference_groups, "count") before
finally calling the count method.
We have seen reports where the blocktranslate tag fails because the
usage_count_val is not a number. We haven't got a reproducible example,
but this would help surface any errors, as the exception would be raised
from the Python code rather than the template.
Currently, the code that handles the POST request for reverting a
revision lives in the EditView class, while the revisions_revert view is
a smaller view that tries to "mimic" the EditView for rendering the view
as part of a GET request. The view injects the revision ID into the
form, which has the action URL hardcoded to the EditView. Including the
revision ID in the form allows the EditView to tell whether it's in a
"reverting" mode or not, and adjust the POST logic accordingly.
However, this results in possible inconsistencies in both views.
Whenever we want to change EditView code or template, we need to make
sure to also update the revisions_revert view. The fact that the
revisions_revert view is a function-based view doesn't help.
Instead of copying the view code and reusing the template with the
addition of injecting the revision ID in the form, turn it into a proper
subclass of the EditView, and make use of Django's URL patterns to
retrieve the revision ID in the EditView.
This approach is similar to how reverting revisions is handled for
snippets.
Ideally, all the code for handling revisions revert should live in the
RevisionsRevertView, and the EditView shouldn't know about it at all.
This is how it's done for snippets: all the revisions revert-related
code is put in RevisionsRevertMixin.
However, this is currently not possible for pages without more
significant refactoring, so this commit does the minimal change needed
to achieve the goal of keeping the revisions_revert view in sync with
the EditView.