Use a CollectionQuerySet method to simplify displaying indented collection lists

pull/8579/head
Matt Westcott 2022-06-28 18:29:55 +01:00 zatwierdzone przez Matt Westcott
rodzic 988b7c8c39
commit 7fd45a6693
6 zmienionych plików z 30 dodań i 64 usunięć

Wyświetl plik

@ -13,13 +13,12 @@
</tr>
</thead>
<tbody>
{% minimum_collection_depth collections as min_depth %}
{% for collection in collections %}
{% for pk, display_name in collections.get_indented_choices %}
<tr>
<td class="title">
<div class="title-wrapper">
<a href="{% url 'wagtailadmin_collections:edit' collection.id %}">
{% format_collection collection min_depth %}
<a href="{% url 'wagtailadmin_collections:edit' pk %}">
{{ display_name }}
</a>
</div>
</td>

Wyświetl plik

@ -1,4 +1,4 @@
{% load i18n l10n wagtailadmin_tags %}
{% load i18n l10n %}
<li {% if li_classes %}class="{{ li_classes }}"{% endif %}>
<div class="field choice_field select">
@ -7,17 +7,10 @@
<div class="input">
<select id="collection_chooser_collection_id" name="collection_id">
<option value="">{% trans "All collections" %}</option>
{% minimum_collection_depth collections as min_depth %}
{% for collection in collections %}
<option value="{{ collection.id|unlocalize }}"
{% if collection == current_collection %}selected="selected"{% endif %}>
{% if request.user.is_superuser %}
{# Superuser may see all collections #}
{% format_collection collection %}
{% else %}
{# Pass the minimum depth of the permitted collections, since user isn't a superuser #}
{% format_collection collection min_depth %}
{% endif %}
{% for pk, display_name in collections.get_indented_choices %}
<option value="{{ pk|unlocalize }}"
{% if pk == current_collection.pk %}selected="selected"{% endif %}>
{{ display_name }}
</option>
{% endfor %}
</select>

Wyświetl plik

@ -7,7 +7,6 @@ from django.conf import settings
from django.contrib.admin.utils import quote
from django.contrib.humanize.templatetags.humanize import intcomma, naturaltime
from django.contrib.messages.constants import DEFAULT_TAGS as MESSAGE_TAGS
from django.db.models import Min, QuerySet
from django.shortcuts import resolve_url as resolve_url_func
from django.template.defaultfilters import stringfilter
from django.templatetags.static import static
@ -40,7 +39,6 @@ from wagtail.coreutils import (
get_locales_display_names,
)
from wagtail.models import (
Collection,
CollectionViewRestriction,
Locale,
Page,
@ -729,30 +727,6 @@ def timesince_last_update(
return _("%(time_period)s ago") % {"time_period": timesince(last_update)}
@register.simple_tag
def format_collection(coll: Collection, min_depth: int = 2) -> str:
"""
Renders a given Collection's name as a formatted string that displays its
hierarchical depth via indentation. If min_depth is supplied, the
Collection's depth is rendered relative to that depth. min_depth defaults
to 2, the depth of the first non-Root Collection.
Example usage: {% format_collection collection min_depth %}
Example output: "&nbsp;&nbsp;&nbsp;&nbsp;&#x21b3 Child Collection"
"""
return coll.get_indented_name(min_depth, html=True)
@register.simple_tag
def minimum_collection_depth(collections: QuerySet) -> int:
"""
Returns the minimum depth of the Collections in the given queryset.
Call this before beginning a loop through Collections that will
use {% format_collection collection min_depth %}.
"""
return collections.aggregate(Min("depth"))["depth__min"] or 2
@register.filter
def user_display_name(user):
"""

Wyświetl plik

@ -29,16 +29,9 @@
<label for="id_adddocument_collection">{% trans "Add to collection:" %}</label>
<div class="field-content">
<select id="id_adddocument_collection" name="collection">
{% minimum_collection_depth collections as min_depth %}
{% for collection in collections %}
<option value="{{ collection.id|unlocalize }}">
{% if request.user.is_superuser %}
{# Superuser may see all collections. #}
{% format_collection collection %}
{% else %}
{# Pass the minimum depth of the permitted collections, since user isn't a superuser #}
{% format_collection collection min_depth %}
{% endif %}
{% for pk, display_name in collections.get_indented_choices %}
<option value="{{ pk|unlocalize }}">
{{ display_name }}
</option>
{% endfor %}
</select>

Wyświetl plik

@ -29,16 +29,9 @@
<label for="id_addimage_collection">{% trans "Add to collection:" %}</label>
<div class="field-content">
<select id="id_addimage_collection" name="collection">
{% minimum_collection_depth collections as min_depth %}
{% for collection in collections %}
<option value="{{ collection.id|unlocalize }}">
{% if request.user.is_superuser %}
{# Superuser may see all collections. #}
{% format_collection collection %}
{% else %}
{# Pass the minimum depth of the permitted collections, since user isn't a superuser #}
{% format_collection collection min_depth %}
{% endif %}
{% for pk, display_name in collections.get_indented_choices %}
<option value="{{ pk|unlocalize }}">
{{ display_name }}
</option>
{% endfor %}
</select>

Wyświetl plik

@ -11,12 +11,26 @@ from wagtail.search import index
from .view_restrictions import BaseViewRestriction
class CollectionQuerySet(TreeQuerySet):
def get_indented_choices(self):
"""
Return a list of (id, label) tuples for use as a list of choices in a collection chooser
dropdown, where the label is formatted with get_indented_name to provide a tree layout.
The indent level is chosen to place the minimum-depth collection at indent 0.
"""
min_depth = self.aggregate(models.Min("depth"))["depth__min"] or 2
return [
(collection.pk, collection.get_indented_name(min_depth, html=True))
for collection in self
]
class BaseCollectionManager(models.Manager):
def get_queryset(self):
return TreeQuerySet(self.model).order_by("path")
return CollectionQuerySet(self.model).order_by("path")
CollectionManager = BaseCollectionManager.from_queryset(TreeQuerySet)
CollectionManager = BaseCollectionManager.from_queryset(CollectionQuerySet)
class CollectionViewRestriction(BaseViewRestriction):