kopia lustrzana https://github.com/wagtail/wagtail
Implement nested collections
rodzic
0d8301e28f
commit
e404f83cd1
|
@ -3,6 +3,7 @@ from itertools import groupby
|
|||
from django import forms
|
||||
from django.contrib.auth.models import Group, Permission
|
||||
from django.db import transaction
|
||||
from django.db.models import Min
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
|
@ -18,11 +19,76 @@ class CollectionViewRestrictionForm(BaseViewRestrictionForm):
|
|||
fields = ('restriction_type', 'password', 'groups')
|
||||
|
||||
|
||||
class SelectWithDisabledOptions(forms.Select):
|
||||
"""
|
||||
Subclass of Django's select widget that allows disabling options.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.disabled_values = ()
|
||||
|
||||
def create_option(self, name, value, *args, **kwargs):
|
||||
option_dict = super().create_option(name, value, *args, **kwargs)
|
||||
if value in self.disabled_values:
|
||||
option_dict['attrs']['disabled'] = 'disabled'
|
||||
return option_dict
|
||||
|
||||
|
||||
class CollectionChoiceField(forms.ModelChoiceField):
|
||||
widget = SelectWithDisabledOptions
|
||||
|
||||
def __init__(self, *args, disabled_queryset=None, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._indentation_start_depth = 2
|
||||
self.disabled_queryset = disabled_queryset
|
||||
|
||||
def _get_disabled_queryset(self):
|
||||
return self._disabled_queryset
|
||||
|
||||
def _set_disabled_queryset(self, queryset):
|
||||
self._disabled_queryset = queryset
|
||||
if queryset is None:
|
||||
self.widget.disabled_values = ()
|
||||
else:
|
||||
self.widget.disabled_values = queryset.values_list(self.to_field_name or 'pk', flat=True)
|
||||
|
||||
disabled_queryset = property(_get_disabled_queryset, _set_disabled_queryset)
|
||||
|
||||
def _set_queryset(self, queryset):
|
||||
min_depth = self.queryset.aggregate(Min('depth'))['depth__min']
|
||||
if min_depth is None:
|
||||
self._indentation_start_depth = 2
|
||||
else:
|
||||
self._indentation_start_depth = min_depth + 1
|
||||
|
||||
def label_from_instance(self, obj):
|
||||
return obj.get_indented_name(self._indentation_start_depth, html=True)
|
||||
|
||||
|
||||
class CollectionForm(forms.ModelForm):
|
||||
parent = CollectionChoiceField(
|
||||
queryset=Collection.objects.all(),
|
||||
required=False,
|
||||
help_text=_(
|
||||
"Select hierarchical position. Note: a collection cannot become a child of itself or one of its "
|
||||
"descendants."
|
||||
)
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = Collection
|
||||
fields = ('name',)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
if self.instance._state.adding:
|
||||
self.initial['parent'] = Collection.get_first_root_node().pk
|
||||
else:
|
||||
self.initial['parent'] = self.instance.get_parent().pk
|
||||
self.fields['parent'].disabled_queryset = self.instance.get_descendants(inclusive=True)
|
||||
|
||||
|
||||
class BaseCollectionMemberForm(forms.ModelForm):
|
||||
"""
|
||||
|
@ -212,8 +278,9 @@ def collection_member_permission_formset_factory(
|
|||
defines the permissions that are assigned to an entity
|
||||
(i.e. group or user) for a specific collection
|
||||
"""
|
||||
collection = forms.ModelChoiceField(
|
||||
queryset=Collection.objects.all().prefetch_related('group_permissions')
|
||||
collection = CollectionChoiceField(
|
||||
queryset=Collection.objects.all().prefetch_related('group_permissions'),
|
||||
empty_label=None
|
||||
)
|
||||
permissions = PermissionMultipleChoiceField(
|
||||
queryset=permission_queryset,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "wagtailadmin/generic/index.html" %}
|
||||
{% load i18n %}
|
||||
{% load i18n wagtailadmin_tags %}
|
||||
|
||||
{% block listing %}
|
||||
<div class="nice-padding">
|
||||
|
@ -14,11 +14,14 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% minimum_collection_depth collections as min_depth %}
|
||||
{% for collection in collections %}
|
||||
<tr>
|
||||
<td class="title">
|
||||
<div class="title-wrapper">
|
||||
<a href="{% url 'wagtailadmin_collections:edit' collection.id %}">{{ collection }}</a>
|
||||
<a href="{% url 'wagtailadmin_collections:edit' collection.id %}">
|
||||
{% format_collection collection min_depth %}
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
{% load i18n %}
|
||||
{% load l10n %}
|
||||
{% load i18n l10n wagtailadmin_tags %}
|
||||
|
||||
<li>
|
||||
<div class="field choice_field select">
|
||||
|
@ -8,8 +7,18 @@
|
|||
<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 %}>{{ collection.name }}</option>
|
||||
<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 %}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<span></span>
|
||||
|
|
|
@ -10,6 +10,7 @@ from django.conf import settings
|
|||
from django.contrib.admin.utils import quote
|
||||
from django.contrib.humanize.templatetags.humanize import intcomma
|
||||
from django.contrib.messages.constants import DEFAULT_TAGS as MESSAGE_TAGS
|
||||
from django.db.models import Min, QuerySet
|
||||
from django.template.defaultfilters import stringfilter
|
||||
from django.template.loader import render_to_string
|
||||
from django.templatetags.static import static
|
||||
|
@ -27,7 +28,7 @@ from wagtail.admin.search import admin_search_areas
|
|||
from wagtail.admin.staticfiles import versioned_static as versioned_static_func
|
||||
from wagtail.core import hooks
|
||||
from wagtail.core.models import (
|
||||
CollectionViewRestriction, Page, PageLogEntry, PageViewRestriction, UserPagePermissionsProxy)
|
||||
Collection, CollectionViewRestriction, Page, PageLogEntry, PageViewRestriction, UserPagePermissionsProxy)
|
||||
from wagtail.core.utils import cautious_slugify as _cautious_slugify
|
||||
from wagtail.core.utils import accepts_kwarg, camelcase_to_underscore, escape_script
|
||||
from wagtail.users.utils import get_gravatar_url
|
||||
|
@ -603,3 +604,27 @@ def format_action_log_message(log_entry):
|
|||
if not isinstance(log_entry, PageLogEntry):
|
||||
return ''
|
||||
return log_action_registry.format_message(log_entry)
|
||||
|
||||
|
||||
@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: " ↳ 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
|
||||
|
|
|
@ -21,8 +21,8 @@ class Index(IndexView):
|
|||
header_icon = 'folder-open-1'
|
||||
|
||||
def get_queryset(self):
|
||||
# Only return children of the root node, so that the root is not editable
|
||||
return Collection.get_first_root_node().get_children().order_by('name')
|
||||
# Only return descendants of the root node, so that the root is not editable
|
||||
return Collection.get_first_root_node().get_descendants()
|
||||
|
||||
|
||||
class Create(CreateView):
|
||||
|
@ -36,10 +36,10 @@ class Create(CreateView):
|
|||
header_icon = 'folder-open-1'
|
||||
|
||||
def save_instance(self):
|
||||
# Always create new collections as children of root
|
||||
instance = self.form.save(commit=False)
|
||||
root_collection = Collection.get_first_root_node()
|
||||
root_collection.add_child(instance=instance)
|
||||
parent_pk = self.form.data.get('parent')
|
||||
parent = Collection.objects.get(pk=parent_pk) if parent_pk else Collection.get_first_root_node()
|
||||
parent.add_child(instance=instance)
|
||||
return instance
|
||||
|
||||
|
||||
|
@ -57,9 +57,26 @@ class Edit(EditView):
|
|||
context_object_name = 'collection'
|
||||
header_icon = 'folder-open-1'
|
||||
|
||||
def save_instance(self):
|
||||
instance = self.form.save()
|
||||
parent_pk = self.form.data.get('parent')
|
||||
if parent_pk and parent_pk != instance.get_parent().pk:
|
||||
instance.move(Collection.objects.get(pk=parent_pk), 'sorted-child')
|
||||
return instance
|
||||
|
||||
def form_valid(self, form):
|
||||
new_parent_pk = int(form.data.get('parent', 0))
|
||||
old_descendants = list(form.instance.get_descendants(
|
||||
inclusive=True).values_list('pk', flat=True)
|
||||
)
|
||||
if new_parent_pk in old_descendants:
|
||||
form.add_error('parent', gettext_lazy('Please select another parent'))
|
||||
return self.form_invalid(form)
|
||||
return super().form_valid(form)
|
||||
|
||||
def get_queryset(self):
|
||||
# Only return children of the root node, so that the root is not editable
|
||||
return Collection.get_first_root_node().get_children().order_by('name')
|
||||
# Only return descendants of the root node, so that the root is not editable
|
||||
return Collection.get_first_root_node().get_descendants().order_by('path')
|
||||
|
||||
|
||||
class Delete(DeleteView):
|
||||
|
@ -74,7 +91,7 @@ class Delete(DeleteView):
|
|||
|
||||
def get_queryset(self):
|
||||
# Only return children of the root node, so that the root is not editable
|
||||
return Collection.get_first_root_node().get_children().order_by('name')
|
||||
return Collection.get_first_root_node().get_descendants().order_by('path')
|
||||
|
||||
def get_collection_contents(self):
|
||||
collection_contents = [
|
||||
|
|
|
@ -14,7 +14,7 @@ from django.core.exceptions import PermissionDenied, ValidationError
|
|||
from django.core.handlers.base import BaseHandler
|
||||
from django.core.handlers.wsgi import WSGIRequest
|
||||
from django.db import models, transaction
|
||||
from django.db.models import Case, Q, Value, When
|
||||
from django.db.models import Q, Value
|
||||
from django.db.models.expressions import OuterRef, Subquery
|
||||
from django.db.models.functions import Concat, Lower, Substr
|
||||
from django.http import Http404
|
||||
|
@ -25,7 +25,9 @@ from django.utils import timezone
|
|||
from django.utils.cache import patch_cache_control
|
||||
from django.utils.encoding import force_str
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.html import format_html
|
||||
from django.utils.module_loading import import_string
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.text import capfirst, slugify
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from modelcluster.fields import ParentalKey, ParentalManyToManyField
|
||||
|
@ -2738,6 +2740,8 @@ class Collection(TreebeardPathFixMixin, MP_Node):
|
|||
name = models.CharField(max_length=255, verbose_name=_('name'))
|
||||
|
||||
objects = CollectionManager()
|
||||
# Tell treebeard to order Collections' paths such that they are ordered by name at each level.
|
||||
node_order_by = ['name']
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
@ -2761,13 +2765,33 @@ class Collection(TreebeardPathFixMixin, MP_Node):
|
|||
"""Return a query set of all collection view restrictions that apply to this collection"""
|
||||
return CollectionViewRestriction.objects.filter(collection__in=self.get_ancestors(inclusive=True))
|
||||
|
||||
@staticmethod
|
||||
def order_for_display(queryset):
|
||||
return queryset.annotate(
|
||||
display_order=Case(
|
||||
When(depth=1, then=Value('')),
|
||||
default='name')
|
||||
).order_by('display_order')
|
||||
def get_indented_name(self, indentation_start_depth=2, html=False):
|
||||
"""
|
||||
Renders this Collection's name as a formatted string that displays its hierarchical depth via indentation.
|
||||
If indentation_start_depth is supplied, the Collection's depth is rendered relative to that depth.
|
||||
indentation_start_depth defaults to 2, the depth of the first non-Root Collection.
|
||||
Pass html=True to get a HTML representation, instead of the default plain-text.
|
||||
|
||||
Example text output: " ↳ Pies"
|
||||
Example HTML output: " ↳ Pies"
|
||||
"""
|
||||
display_depth = self.depth - indentation_start_depth
|
||||
# A Collection with a display depth of 0 or less (Root's can be -1), should have no indent.
|
||||
if display_depth <= 0:
|
||||
return self.name
|
||||
|
||||
# Indent each level of depth by 4 spaces (the width of the ↳ character in our admin font), then add ↳
|
||||
# before adding the name.
|
||||
if html:
|
||||
# NOTE: ↳ is the hex HTML entity for ↳.
|
||||
return format_html(
|
||||
"{indent}{icon} {name}",
|
||||
indent=mark_safe(' ' * 4 * display_depth),
|
||||
icon=mark_safe('↳'),
|
||||
name=self.name
|
||||
)
|
||||
# Output unicode plain-text version
|
||||
return "{}↳ {}".format(' ' * 4 * display_depth, self.name)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('collection')
|
||||
|
|
|
@ -2,6 +2,7 @@ from django.conf import settings
|
|||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.auth.views import redirect_to_login
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import ngettext
|
||||
|
||||
from wagtail.core import hooks
|
||||
from wagtail.core.models import PageViewRestriction
|
||||
|
@ -75,3 +76,19 @@ def register_task_permissions():
|
|||
content_type__app_label='wagtailcore',
|
||||
codename__in=['add_task', 'change_task', 'delete_task']
|
||||
)
|
||||
|
||||
|
||||
@hooks.register('describe_collection_contents')
|
||||
def describe_collection_children(collection):
|
||||
descendant_count = collection.get_descendants().count()
|
||||
if descendant_count:
|
||||
url = reverse('wagtailadmin_collections:index')
|
||||
return {
|
||||
'count': descendant_count,
|
||||
'count_text': ngettext(
|
||||
"%(count)s descendant collection",
|
||||
"%(count)s descendant collections",
|
||||
descendant_count
|
||||
) % {'count': descendant_count},
|
||||
'url': url,
|
||||
}
|
||||
|
|
|
@ -4,11 +4,21 @@ from django.utils.translation import gettext_lazy as _
|
|||
|
||||
from wagtail.admin import widgets
|
||||
from wagtail.admin.forms.collections import (
|
||||
BaseCollectionMemberForm, collection_member_permission_formset_factory)
|
||||
BaseCollectionMemberForm, CollectionChoiceField, collection_member_permission_formset_factory)
|
||||
from wagtail.core.models import Collection
|
||||
from wagtail.documents.models import Document
|
||||
from wagtail.documents.permissions import permission_policy as documents_permission_policy
|
||||
|
||||
|
||||
# Callback to allow us to override the default form field for the collection field
|
||||
def formfield_for_dbfield(db_field, **kwargs):
|
||||
if db_field.name == 'collection':
|
||||
return CollectionChoiceField(queryset=Collection.objects.all(), empty_label=None, **kwargs)
|
||||
|
||||
# For all other fields, just call its formfield() method.
|
||||
return db_field.formfield(**kwargs)
|
||||
|
||||
|
||||
class BaseDocumentForm(BaseCollectionMemberForm):
|
||||
permission_policy = documents_permission_policy
|
||||
|
||||
|
@ -26,6 +36,7 @@ def get_document_form(model):
|
|||
model,
|
||||
form=BaseDocumentForm,
|
||||
fields=fields,
|
||||
formfield_callback=formfield_for_dbfield,
|
||||
widgets={
|
||||
'tags': widgets.AdminTagWidget,
|
||||
'file': forms.FileInput()
|
||||
|
@ -41,6 +52,7 @@ def get_document_multi_form(model):
|
|||
model,
|
||||
form=BaseDocumentForm,
|
||||
fields=fields,
|
||||
formfield_callback=formfield_for_dbfield,
|
||||
widgets={
|
||||
'tags': widgets.AdminTagWidget,
|
||||
'file': forms.FileInput()
|
||||
|
|
|
@ -30,14 +30,20 @@
|
|||
<div class="field choice_field select">
|
||||
<label for="id_adddocument_collection">{% trans "Add to collection:" %}</label>
|
||||
<div class="field-content">
|
||||
<div class="input">
|
||||
<select id="id_adddocument_collection" name="collection">
|
||||
{% for collection in collections %}
|
||||
<option value="{{ collection.id|unlocalize }}">{{ collection.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<span></span>
|
||||
</div>
|
||||
<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 %}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
|
@ -93,8 +93,6 @@ def chooser(request):
|
|||
collections = Collection.objects.all()
|
||||
if len(collections) < 2:
|
||||
collections = None
|
||||
else:
|
||||
collections = Collection.order_for_display(collections)
|
||||
|
||||
documents = documents.order_by('-created_at')
|
||||
documents_exist = documents.exists()
|
||||
|
|
|
@ -66,8 +66,6 @@ def index(request):
|
|||
)
|
||||
if len(collections) < 2:
|
||||
collections = None
|
||||
else:
|
||||
collections = Collection.order_for_display(collections)
|
||||
|
||||
# Create response
|
||||
if request.is_ajax():
|
||||
|
|
|
@ -8,7 +8,6 @@ from django.views.decorators.http import require_POST
|
|||
from django.views.decorators.vary import vary_on_headers
|
||||
|
||||
from wagtail.admin.auth import PermissionPolicyChecker
|
||||
from wagtail.core.models import Collection
|
||||
from wagtail.search.backends import get_search_backends
|
||||
|
||||
from .. import get_document_model
|
||||
|
@ -26,11 +25,9 @@ def add(request):
|
|||
DocumentMultiForm = get_document_multi_form(Document)
|
||||
|
||||
collections = permission_policy.collections_user_has_permission_for(request.user, 'add')
|
||||
if len(collections) > 1:
|
||||
collections_to_choose = Collection.order_for_display(collections)
|
||||
else:
|
||||
if len(collections) < 2:
|
||||
# no need to show a collections chooser
|
||||
collections_to_choose = None
|
||||
collections = None
|
||||
|
||||
if request.method == 'POST':
|
||||
if not request.is_ajax():
|
||||
|
@ -86,7 +83,7 @@ def add(request):
|
|||
|
||||
return TemplateResponse(request, 'wagtaildocs/multiple/add.html', {
|
||||
'help_text': form.fields['file'].help_text,
|
||||
'collections': collections_to_choose,
|
||||
'collections': collections,
|
||||
'form_media': form.media,
|
||||
})
|
||||
|
||||
|
|
|
@ -5,18 +5,21 @@ from django.utils.translation import gettext as _
|
|||
|
||||
from wagtail.admin import widgets
|
||||
from wagtail.admin.forms.collections import (
|
||||
BaseCollectionMemberForm, collection_member_permission_formset_factory)
|
||||
BaseCollectionMemberForm, CollectionChoiceField, collection_member_permission_formset_factory)
|
||||
from wagtail.core.models import Collection
|
||||
from wagtail.images.fields import WagtailImageField
|
||||
from wagtail.images.formats import get_image_formats
|
||||
from wagtail.images.models import Image
|
||||
from wagtail.images.permissions import permission_policy as images_permission_policy
|
||||
|
||||
|
||||
# Callback to allow us to override the default form field for the image file field
|
||||
# Callback to allow us to override the default form field for the image file field and collection field.
|
||||
def formfield_for_dbfield(db_field, **kwargs):
|
||||
# Check if this is the file field
|
||||
if db_field.name == 'file':
|
||||
return WagtailImageField(label=capfirst(db_field.verbose_name), **kwargs)
|
||||
elif db_field.name == 'collection':
|
||||
return CollectionChoiceField(queryset=Collection.objects.all(), empty_label=None, **kwargs)
|
||||
|
||||
# For all other fields, just call its formfield() method.
|
||||
return db_field.formfield(**kwargs)
|
||||
|
|
|
@ -30,14 +30,20 @@
|
|||
<div class="field choice_field select">
|
||||
<label for="id_addimage_collection">{% trans "Add to collection:" %}</label>
|
||||
<div class="field-content">
|
||||
<div class="input">
|
||||
<select id="id_addimage_collection" name="collection">
|
||||
{% for collection in collections %}
|
||||
<option value="{{ collection.id|unlocalize }}">{{ collection.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<span></span>
|
||||
</div>
|
||||
<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 %}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
|
@ -57,8 +57,6 @@ def get_chooser_context(request):
|
|||
collections = Collection.objects.all()
|
||||
if len(collections) < 2:
|
||||
collections = None
|
||||
else:
|
||||
collections = Collection.order_for_display(collections)
|
||||
|
||||
return {
|
||||
'searchform': SearchForm(),
|
||||
|
|
|
@ -76,8 +76,6 @@ def index(request):
|
|||
)
|
||||
if len(collections) < 2:
|
||||
collections = None
|
||||
else:
|
||||
collections = Collection.order_for_display(collections)
|
||||
|
||||
# Create response
|
||||
if request.is_ajax():
|
||||
|
|
|
@ -10,7 +10,6 @@ from django.views.decorators.http import require_POST
|
|||
from django.views.decorators.vary import vary_on_headers
|
||||
|
||||
from wagtail.admin.auth import PermissionPolicyChecker
|
||||
from wagtail.core.models import Collection
|
||||
from wagtail.images import get_image_model
|
||||
from wagtail.images.fields import ALLOWED_EXTENSIONS
|
||||
from wagtail.images.forms import get_image_form
|
||||
|
@ -46,11 +45,9 @@ def add(request):
|
|||
ImageForm = get_image_form(Image)
|
||||
|
||||
collections = permission_policy.collections_user_has_permission_for(request.user, 'add')
|
||||
if len(collections) > 1:
|
||||
collections_to_choose = Collection.order_for_display(collections)
|
||||
else:
|
||||
if len(collections) < 2:
|
||||
# no need to show a collections chooser
|
||||
collections_to_choose = None
|
||||
collections = None
|
||||
|
||||
if request.method == 'POST':
|
||||
if not request.is_ajax():
|
||||
|
@ -128,7 +125,7 @@ def add(request):
|
|||
'allowed_extensions': ALLOWED_EXTENSIONS,
|
||||
'error_max_file_size': form.fields['file'].error_messages['file_too_large_unknown_size'],
|
||||
'error_accepted_file_types': form.fields['file'].error_messages['invalid_image_extension'],
|
||||
'collections': collections_to_choose,
|
||||
'collections': collections,
|
||||
'form_media': form.media,
|
||||
})
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue