Mr Duhaz пре 1 месец
родитељ
комит
3c4326fced
100 измењених фајлова са 0 додато и 2983 уклоњено
  1. 0 52
      static/admin/__init__.py
  2. 0 94
      static/admin/actions.py
  3. 0 27
      static/admin/apps.py
  4. 0 1359
      static/admin/checks.py
  5. 0 0
      static/admin/css/autocomplete.css
  6. 0 0
      static/admin/css/base.css
  7. 0 0
      static/admin/css/changelists.css
  8. 0 0
      static/admin/css/dark_mode.css
  9. 0 0
      static/admin/css/dashboard.css
  10. 0 0
      static/admin/css/forms.css
  11. 0 0
      static/admin/css/login.css
  12. 0 0
      static/admin/css/nav_sidebar.css
  13. 0 0
      static/admin/css/responsive.css
  14. 0 0
      static/admin/css/responsive_rtl.css
  15. 0 0
      static/admin/css/rtl.css
  16. 0 0
      static/admin/css/unusable_password_field.css
  17. 0 0
      static/admin/css/vendor/select2/LICENSE-SELECT2.md
  18. 0 0
      static/admin/css/vendor/select2/select2.css
  19. 0 0
      static/admin/css/vendor/select2/select2.min.css
  20. 0 0
      static/admin/css/widgets.css
  21. 0 111
      static/admin/decorators.py
  22. 0 25
      static/admin/exceptions.py
  23. 0 716
      static/admin/filters.py
  24. 0 31
      static/admin/forms.py
  25. 0 568
      static/admin/helpers.py
  26. 0 0
      static/admin/img/LICENSE
  27. 0 0
      static/admin/img/README.txt
  28. 0 0
      static/admin/img/calendar-icons.svg
  29. 0 0
      static/admin/img/gis/move_vertex_off.svg
  30. 0 0
      static/admin/img/gis/move_vertex_on.svg
  31. 0 0
      static/admin/img/icon-addlink.svg
  32. 0 0
      static/admin/img/icon-alert.svg
  33. 0 0
      static/admin/img/icon-calendar.svg
  34. 0 0
      static/admin/img/icon-changelink.svg
  35. 0 0
      static/admin/img/icon-clock.svg
  36. 0 0
      static/admin/img/icon-deletelink.svg
  37. 0 0
      static/admin/img/icon-hidelink.svg
  38. 0 0
      static/admin/img/icon-no.svg
  39. 0 0
      static/admin/img/icon-unknown-alt.svg
  40. 0 0
      static/admin/img/icon-unknown.svg
  41. 0 0
      static/admin/img/icon-viewlink.svg
  42. 0 0
      static/admin/img/icon-yes.svg
  43. 0 0
      static/admin/img/inline-delete.svg
  44. 0 0
      static/admin/img/search.svg
  45. 0 0
      static/admin/img/selector-icons.svg
  46. 0 0
      static/admin/img/sorting-icons.svg
  47. 0 0
      static/admin/img/tooltag-add.svg
  48. 0 0
      static/admin/img/tooltag-arrowright.svg
  49. 0 0
      static/admin/js/SelectBox.js
  50. 0 0
      static/admin/js/SelectFilter2.js
  51. 0 0
      static/admin/js/actions.js
  52. 0 0
      static/admin/js/admin/DateTimeShortcuts.js
  53. 0 0
      static/admin/js/admin/RelatedObjectLookups.js
  54. 0 0
      static/admin/js/autocomplete.js
  55. 0 0
      static/admin/js/calendar.js
  56. 0 0
      static/admin/js/cancel.js
  57. 0 0
      static/admin/js/change_form.js
  58. 0 0
      static/admin/js/core.js
  59. 0 0
      static/admin/js/filters.js
  60. 0 0
      static/admin/js/inlines.js
  61. 0 0
      static/admin/js/jquery.init.js
  62. 0 0
      static/admin/js/nav_sidebar.js
  63. 0 0
      static/admin/js/popup_response.js
  64. 0 0
      static/admin/js/prepopulate.js
  65. 0 0
      static/admin/js/prepopulate_init.js
  66. 0 0
      static/admin/js/theme.js
  67. 0 0
      static/admin/js/unusable_password_field.js
  68. 0 0
      static/admin/js/urlify.js
  69. 0 0
      static/admin/js/vendor/jquery/LICENSE.txt
  70. 0 0
      static/admin/js/vendor/jquery/jquery.js
  71. 0 0
      static/admin/js/vendor/jquery/jquery.min.js
  72. 0 0
      static/admin/js/vendor/select2/LICENSE.md
  73. 0 0
      static/admin/js/vendor/select2/i18n/af.js
  74. 0 0
      static/admin/js/vendor/select2/i18n/ar.js
  75. 0 0
      static/admin/js/vendor/select2/i18n/az.js
  76. 0 0
      static/admin/js/vendor/select2/i18n/bg.js
  77. 0 0
      static/admin/js/vendor/select2/i18n/bn.js
  78. 0 0
      static/admin/js/vendor/select2/i18n/bs.js
  79. 0 0
      static/admin/js/vendor/select2/i18n/ca.js
  80. 0 0
      static/admin/js/vendor/select2/i18n/cs.js
  81. 0 0
      static/admin/js/vendor/select2/i18n/da.js
  82. 0 0
      static/admin/js/vendor/select2/i18n/de.js
  83. 0 0
      static/admin/js/vendor/select2/i18n/dsb.js
  84. 0 0
      static/admin/js/vendor/select2/i18n/el.js
  85. 0 0
      static/admin/js/vendor/select2/i18n/en.js
  86. 0 0
      static/admin/js/vendor/select2/i18n/es.js
  87. 0 0
      static/admin/js/vendor/select2/i18n/et.js
  88. 0 0
      static/admin/js/vendor/select2/i18n/eu.js
  89. 0 0
      static/admin/js/vendor/select2/i18n/fa.js
  90. 0 0
      static/admin/js/vendor/select2/i18n/fi.js
  91. 0 0
      static/admin/js/vendor/select2/i18n/fr.js
  92. 0 0
      static/admin/js/vendor/select2/i18n/gl.js
  93. 0 0
      static/admin/js/vendor/select2/i18n/he.js
  94. 0 0
      static/admin/js/vendor/select2/i18n/hi.js
  95. 0 0
      static/admin/js/vendor/select2/i18n/hr.js
  96. 0 0
      static/admin/js/vendor/select2/i18n/hsb.js
  97. 0 0
      static/admin/js/vendor/select2/i18n/hu.js
  98. 0 0
      static/admin/js/vendor/select2/i18n/hy.js
  99. 0 0
      static/admin/js/vendor/select2/i18n/id.js
  100. 0 0
      static/admin/js/vendor/select2/i18n/is.js

+ 0 - 52
static/admin/__init__.py

@@ -1,52 +0,0 @@
-from django.contrib.admin.decorators import action, display, register
-from django.contrib.admin.filters import (
-    AllValuesFieldListFilter,
-    BooleanFieldListFilter,
-    ChoicesFieldListFilter,
-    DateFieldListFilter,
-    EmptyFieldListFilter,
-    FieldListFilter,
-    ListFilter,
-    RelatedFieldListFilter,
-    RelatedOnlyFieldListFilter,
-    SimpleListFilter,
-)
-from django.contrib.admin.options import (
-    HORIZONTAL,
-    VERTICAL,
-    ModelAdmin,
-    ShowFacets,
-    StackedInline,
-    TabularInline,
-)
-from django.contrib.admin.sites import AdminSite, site
-from django.utils.module_loading import autodiscover_modules
-
-__all__ = [
-    "action",
-    "display",
-    "register",
-    "ModelAdmin",
-    "HORIZONTAL",
-    "VERTICAL",
-    "StackedInline",
-    "TabularInline",
-    "AdminSite",
-    "site",
-    "ListFilter",
-    "SimpleListFilter",
-    "FieldListFilter",
-    "BooleanFieldListFilter",
-    "RelatedFieldListFilter",
-    "ChoicesFieldListFilter",
-    "DateFieldListFilter",
-    "AllValuesFieldListFilter",
-    "EmptyFieldListFilter",
-    "RelatedOnlyFieldListFilter",
-    "ShowFacets",
-    "autodiscover",
-]
-
-
-def autodiscover():
-    autodiscover_modules("admin", register_to=site)

+ 0 - 94
static/admin/actions.py

@@ -1,94 +0,0 @@
-"""
-Built-in, globally-available admin actions.
-"""
-
-from django.contrib import messages
-from django.contrib.admin import helpers
-from django.contrib.admin.decorators import action
-from django.contrib.admin.utils import model_ngettext
-from django.core.exceptions import PermissionDenied
-from django.template.response import TemplateResponse
-from django.utils.translation import gettext as _
-from django.utils.translation import gettext_lazy
-
-
-@action(
-    permissions=["delete"],
-    description=gettext_lazy("Delete selected %(verbose_name_plural)s"),
-)
-def delete_selected(modeladmin, request, queryset):
-    """
-    Default action which deletes the selected objects.
-
-    This action first displays a confirmation page which shows all the
-    deletable objects, or, if the user has no permission one of the related
-    childs (foreignkeys), a "permission denied" message.
-
-    Next, it deletes all selected objects and redirects back to the change list.
-    """
-    opts = modeladmin.model._meta
-    app_label = opts.app_label
-
-    # Populate deletable_objects, a data structure of all related objects that
-    # will also be deleted.
-    (
-        deletable_objects,
-        model_count,
-        perms_needed,
-        protected,
-    ) = modeladmin.get_deleted_objects(queryset, request)
-
-    # The user has already confirmed the deletion.
-    # Do the deletion and return None to display the change list view again.
-    if request.POST.get("post") and not protected:
-        if perms_needed:
-            raise PermissionDenied
-        n = len(queryset)
-        if n:
-            modeladmin.log_deletions(request, queryset)
-            modeladmin.delete_queryset(request, queryset)
-            modeladmin.message_user(
-                request,
-                _("Successfully deleted %(count)d %(items)s.")
-                % {"count": n, "items": model_ngettext(modeladmin.opts, n)},
-                messages.SUCCESS,
-            )
-        # Return None to display the change list page again.
-        return None
-
-    objects_name = model_ngettext(queryset)
-
-    if perms_needed or protected:
-        title = _("Cannot delete %(name)s") % {"name": objects_name}
-    else:
-        title = _("Are you sure?")
-
-    context = {
-        **modeladmin.admin_site.each_context(request),
-        "title": title,
-        "subtitle": None,
-        "objects_name": str(objects_name),
-        "deletable_objects": [deletable_objects],
-        "model_count": dict(model_count).items(),
-        "queryset": queryset,
-        "perms_lacking": perms_needed,
-        "protected": protected,
-        "opts": opts,
-        "action_checkbox_name": helpers.ACTION_CHECKBOX_NAME,
-        "media": modeladmin.media,
-    }
-
-    request.current_app = modeladmin.admin_site.name
-
-    # Display the confirmation page
-    return TemplateResponse(
-        request,
-        modeladmin.delete_selected_confirmation_template
-        or [
-            "admin/%s/%s/delete_selected_confirmation.html"
-            % (app_label, opts.model_name),
-            "admin/%s/delete_selected_confirmation.html" % app_label,
-            "admin/delete_selected_confirmation.html",
-        ],
-        context,
-    )

+ 0 - 27
static/admin/apps.py

@@ -1,27 +0,0 @@
-from django.apps import AppConfig
-from django.contrib.admin.checks import check_admin_app, check_dependencies
-from django.core import checks
-from django.utils.translation import gettext_lazy as _
-
-
-class SimpleAdminConfig(AppConfig):
-    """Simple AppConfig which does not do automatic discovery."""
-
-    default_auto_field = "django.db.models.AutoField"
-    default_site = "django.contrib.admin.sites.AdminSite"
-    name = "django.contrib.admin"
-    verbose_name = _("Administration")
-
-    def ready(self):
-        checks.register(check_dependencies, checks.Tags.admin)
-        checks.register(check_admin_app, checks.Tags.admin)
-
-
-class AdminConfig(SimpleAdminConfig):
-    """The default AppConfig for admin which does autodiscovery."""
-
-    default = True
-
-    def ready(self):
-        super().ready()
-        self.module.autodiscover()

+ 0 - 1359
static/admin/checks.py

@@ -1,1359 +0,0 @@
-import collections
-from itertools import chain
-
-from django.apps import apps
-from django.conf import settings
-from django.contrib.admin.exceptions import NotRegistered
-from django.contrib.admin.utils import NotRelationField, flatten, get_fields_from_path
-from django.core import checks
-from django.core.exceptions import FieldDoesNotExist
-from django.db import models
-from django.db.models.constants import LOOKUP_SEP
-from django.db.models.expressions import Combinable
-from django.forms.models import BaseModelForm, BaseModelFormSet, _get_foreign_key
-from django.template import engines
-from django.template.backends.django import DjangoTemplates
-from django.utils.module_loading import import_string
-
-
-def _issubclass(cls, classinfo):
-    """
-    issubclass() variant that doesn't raise an exception if cls isn't a
-    class.
-    """
-    try:
-        return issubclass(cls, classinfo)
-    except TypeError:
-        return False
-
-
-def _contains_subclass(class_path, candidate_paths):
-    """
-    Return whether or not a dotted class path (or a subclass of that class) is
-    found in a list of candidate paths.
-    """
-    cls = import_string(class_path)
-    for path in candidate_paths:
-        try:
-            candidate_cls = import_string(path)
-        except ImportError:
-            # ImportErrors are raised elsewhere.
-            continue
-        if _issubclass(candidate_cls, cls):
-            return True
-    return False
-
-
-def check_admin_app(app_configs, **kwargs):
-    from django.contrib.admin.sites import all_sites
-
-    errors = []
-    for site in all_sites:
-        errors.extend(site.check(app_configs))
-    return errors
-
-
-def check_dependencies(**kwargs):
-    """
-    Check that the admin's dependencies are correctly installed.
-    """
-    from django.contrib.admin.sites import all_sites
-
-    if not apps.is_installed("django.contrib.admin"):
-        return []
-    errors = []
-    app_dependencies = (
-        ("django.contrib.contenttypes", 401),
-        ("django.contrib.auth", 405),
-        ("django.contrib.messages", 406),
-    )
-    for app_name, error_code in app_dependencies:
-        if not apps.is_installed(app_name):
-            errors.append(
-                checks.Error(
-                    "'%s' must be in INSTALLED_APPS in order to use the admin "
-                    "application." % app_name,
-                    id="admin.E%d" % error_code,
-                )
-            )
-    for engine in engines.all():
-        if isinstance(engine, DjangoTemplates):
-            django_templates_instance = engine.engine
-            break
-    else:
-        django_templates_instance = None
-    if not django_templates_instance:
-        errors.append(
-            checks.Error(
-                "A 'django.template.backends.django.DjangoTemplates' instance "
-                "must be configured in TEMPLATES in order to use the admin "
-                "application.",
-                id="admin.E403",
-            )
-        )
-    else:
-        if (
-            "django.contrib.auth.context_processors.auth"
-            not in django_templates_instance.context_processors
-            and _contains_subclass(
-                "django.contrib.auth.backends.ModelBackend",
-                settings.AUTHENTICATION_BACKENDS,
-            )
-        ):
-            errors.append(
-                checks.Error(
-                    "'django.contrib.auth.context_processors.auth' must be "
-                    "enabled in DjangoTemplates (TEMPLATES) if using the default "
-                    "auth backend in order to use the admin application.",
-                    id="admin.E402",
-                )
-            )
-        if (
-            "django.contrib.messages.context_processors.messages"
-            not in django_templates_instance.context_processors
-        ):
-            errors.append(
-                checks.Error(
-                    "'django.contrib.messages.context_processors.messages' must "
-                    "be enabled in DjangoTemplates (TEMPLATES) in order to use "
-                    "the admin application.",
-                    id="admin.E404",
-                )
-            )
-        sidebar_enabled = any(site.enable_nav_sidebar for site in all_sites)
-        if (
-            sidebar_enabled
-            and "django.template.context_processors.request"
-            not in django_templates_instance.context_processors
-        ):
-            errors.append(
-                checks.Warning(
-                    "'django.template.context_processors.request' must be enabled "
-                    "in DjangoTemplates (TEMPLATES) in order to use the admin "
-                    "navigation sidebar.",
-                    id="admin.W411",
-                )
-            )
-
-    if not _contains_subclass(
-        "django.contrib.auth.middleware.AuthenticationMiddleware", settings.MIDDLEWARE
-    ):
-        errors.append(
-            checks.Error(
-                "'django.contrib.auth.middleware.AuthenticationMiddleware' must "
-                "be in MIDDLEWARE in order to use the admin application.",
-                id="admin.E408",
-            )
-        )
-    if not _contains_subclass(
-        "django.contrib.messages.middleware.MessageMiddleware", settings.MIDDLEWARE
-    ):
-        errors.append(
-            checks.Error(
-                "'django.contrib.messages.middleware.MessageMiddleware' must "
-                "be in MIDDLEWARE in order to use the admin application.",
-                id="admin.E409",
-            )
-        )
-    if not _contains_subclass(
-        "django.contrib.sessions.middleware.SessionMiddleware", settings.MIDDLEWARE
-    ):
-        errors.append(
-            checks.Error(
-                "'django.contrib.sessions.middleware.SessionMiddleware' must "
-                "be in MIDDLEWARE in order to use the admin application.",
-                hint=(
-                    "Insert "
-                    "'django.contrib.sessions.middleware.SessionMiddleware' "
-                    "before "
-                    "'django.contrib.auth.middleware.AuthenticationMiddleware'."
-                ),
-                id="admin.E410",
-            )
-        )
-    return errors
-
-
-class BaseModelAdminChecks:
-    def check(self, admin_obj, **kwargs):
-        return [
-            *self._check_autocomplete_fields(admin_obj),
-            *self._check_raw_id_fields(admin_obj),
-            *self._check_fields(admin_obj),
-            *self._check_fieldsets(admin_obj),
-            *self._check_exclude(admin_obj),
-            *self._check_form(admin_obj),
-            *self._check_filter_vertical(admin_obj),
-            *self._check_filter_horizontal(admin_obj),
-            *self._check_radio_fields(admin_obj),
-            *self._check_prepopulated_fields(admin_obj),
-            *self._check_view_on_site_url(admin_obj),
-            *self._check_ordering(admin_obj),
-            *self._check_readonly_fields(admin_obj),
-        ]
-
-    def _check_autocomplete_fields(self, obj):
-        """
-        Check that `autocomplete_fields` is a list or tuple of model fields.
-        """
-        if not isinstance(obj.autocomplete_fields, (list, tuple)):
-            return must_be(
-                "a list or tuple",
-                option="autocomplete_fields",
-                obj=obj,
-                id="admin.E036",
-            )
-        else:
-            return list(
-                chain.from_iterable(
-                    [
-                        self._check_autocomplete_fields_item(
-                            obj, field_name, "autocomplete_fields[%d]" % index
-                        )
-                        for index, field_name in enumerate(obj.autocomplete_fields)
-                    ]
-                )
-            )
-
-    def _check_autocomplete_fields_item(self, obj, field_name, label):
-        """
-        Check that an item in `autocomplete_fields` is a ForeignKey or a
-        ManyToManyField and that the item has a related ModelAdmin with
-        search_fields defined.
-        """
-        try:
-            field = obj.model._meta.get_field(field_name)
-        except FieldDoesNotExist:
-            return refer_to_missing_field(
-                field=field_name, option=label, obj=obj, id="admin.E037"
-            )
-        else:
-            if not field.many_to_many and not isinstance(field, models.ForeignKey):
-                return must_be(
-                    "a foreign key or a many-to-many field",
-                    option=label,
-                    obj=obj,
-                    id="admin.E038",
-                )
-            try:
-                related_admin = obj.admin_site.get_model_admin(field.remote_field.model)
-            except NotRegistered:
-                return [
-                    checks.Error(
-                        'An admin for model "%s" has to be registered '
-                        "to be referenced by %s.autocomplete_fields."
-                        % (
-                            field.remote_field.model.__name__,
-                            type(obj).__name__,
-                        ),
-                        obj=obj.__class__,
-                        id="admin.E039",
-                    )
-                ]
-            else:
-                if not related_admin.search_fields:
-                    return [
-                        checks.Error(
-                            '%s must define "search_fields", because it\'s '
-                            "referenced by %s.autocomplete_fields."
-                            % (
-                                related_admin.__class__.__name__,
-                                type(obj).__name__,
-                            ),
-                            obj=obj.__class__,
-                            id="admin.E040",
-                        )
-                    ]
-            return []
-
-    def _check_raw_id_fields(self, obj):
-        """Check that `raw_id_fields` only contains field names that are listed
-        on the model."""
-
-        if not isinstance(obj.raw_id_fields, (list, tuple)):
-            return must_be(
-                "a list or tuple", option="raw_id_fields", obj=obj, id="admin.E001"
-            )
-        else:
-            return list(
-                chain.from_iterable(
-                    self._check_raw_id_fields_item(
-                        obj, field_name, "raw_id_fields[%d]" % index
-                    )
-                    for index, field_name in enumerate(obj.raw_id_fields)
-                )
-            )
-
-    def _check_raw_id_fields_item(self, obj, field_name, label):
-        """Check an item of `raw_id_fields`, i.e. check that field named
-        `field_name` exists in model `model` and is a ForeignKey or a
-        ManyToManyField."""
-
-        try:
-            field = obj.model._meta.get_field(field_name)
-        except FieldDoesNotExist:
-            return refer_to_missing_field(
-                field=field_name, option=label, obj=obj, id="admin.E002"
-            )
-        else:
-            # Using attname is not supported.
-            if field.name != field_name:
-                return refer_to_missing_field(
-                    field=field_name,
-                    option=label,
-                    obj=obj,
-                    id="admin.E002",
-                )
-            if not field.many_to_many and not isinstance(field, models.ForeignKey):
-                return must_be(
-                    "a foreign key or a many-to-many field",
-                    option=label,
-                    obj=obj,
-                    id="admin.E003",
-                )
-            else:
-                return []
-
-    def _check_fields(self, obj):
-        """Check that `fields` only refer to existing fields, doesn't contain
-        duplicates. Check if at most one of `fields` and `fieldsets` is defined.
-        """
-
-        if obj.fields is None:
-            return []
-        elif not isinstance(obj.fields, (list, tuple)):
-            return must_be("a list or tuple", option="fields", obj=obj, id="admin.E004")
-        elif obj.fieldsets:
-            return [
-                checks.Error(
-                    "Both 'fieldsets' and 'fields' are specified.",
-                    obj=obj.__class__,
-                    id="admin.E005",
-                )
-            ]
-        fields = flatten(obj.fields)
-        if len(fields) != len(set(fields)):
-            return [
-                checks.Error(
-                    "The value of 'fields' contains duplicate field(s).",
-                    obj=obj.__class__,
-                    id="admin.E006",
-                )
-            ]
-
-        return list(
-            chain.from_iterable(
-                self._check_field_spec(obj, field_name, "fields")
-                for field_name in obj.fields
-            )
-        )
-
-    def _check_fieldsets(self, obj):
-        """Check that fieldsets is properly formatted and doesn't contain
-        duplicates."""
-
-        if obj.fieldsets is None:
-            return []
-        elif not isinstance(obj.fieldsets, (list, tuple)):
-            return must_be(
-                "a list or tuple", option="fieldsets", obj=obj, id="admin.E007"
-            )
-        else:
-            seen_fields = []
-            return list(
-                chain.from_iterable(
-                    self._check_fieldsets_item(
-                        obj, fieldset, "fieldsets[%d]" % index, seen_fields
-                    )
-                    for index, fieldset in enumerate(obj.fieldsets)
-                )
-            )
-
-    def _check_fieldsets_item(self, obj, fieldset, label, seen_fields):
-        """Check an item of `fieldsets`, i.e. check that this is a pair of a
-        set name and a dictionary containing "fields" key."""
-
-        if not isinstance(fieldset, (list, tuple)):
-            return must_be("a list or tuple", option=label, obj=obj, id="admin.E008")
-        elif len(fieldset) != 2:
-            return must_be("of length 2", option=label, obj=obj, id="admin.E009")
-        elif not isinstance(fieldset[1], dict):
-            return must_be(
-                "a dictionary", option="%s[1]" % label, obj=obj, id="admin.E010"
-            )
-        elif "fields" not in fieldset[1]:
-            return [
-                checks.Error(
-                    "The value of '%s[1]' must contain the key 'fields'." % label,
-                    obj=obj.__class__,
-                    id="admin.E011",
-                )
-            ]
-        elif not isinstance(fieldset[1]["fields"], (list, tuple)):
-            return must_be(
-                "a list or tuple",
-                option="%s[1]['fields']" % label,
-                obj=obj,
-                id="admin.E008",
-            )
-
-        seen_fields.extend(flatten(fieldset[1]["fields"]))
-        if len(seen_fields) != len(set(seen_fields)):
-            return [
-                checks.Error(
-                    "There are duplicate field(s) in '%s[1]'." % label,
-                    obj=obj.__class__,
-                    id="admin.E012",
-                )
-            ]
-        return list(
-            chain.from_iterable(
-                self._check_field_spec(obj, fieldset_fields, '%s[1]["fields"]' % label)
-                for fieldset_fields in fieldset[1]["fields"]
-            )
-        )
-
-    def _check_field_spec(self, obj, fields, label):
-        """`fields` should be an item of `fields` or an item of
-        fieldset[1]['fields'] for any `fieldset` in `fieldsets`. It should be a
-        field name or a tuple of field names."""
-
-        if isinstance(fields, tuple):
-            return list(
-                chain.from_iterable(
-                    self._check_field_spec_item(
-                        obj, field_name, "%s[%d]" % (label, index)
-                    )
-                    for index, field_name in enumerate(fields)
-                )
-            )
-        else:
-            return self._check_field_spec_item(obj, fields, label)
-
-    def _check_field_spec_item(self, obj, field_name, label):
-        if field_name in obj.readonly_fields:
-            # Stuff can be put in fields that isn't actually a model field if
-            # it's in readonly_fields, readonly_fields will handle the
-            # validation of such things.
-            return []
-        else:
-            try:
-                field = obj.model._meta.get_field(field_name)
-            except FieldDoesNotExist:
-                # If we can't find a field on the model that matches, it could
-                # be an extra field on the form.
-                return []
-            else:
-                if (
-                    isinstance(field, models.ManyToManyField)
-                    and not field.remote_field.through._meta.auto_created
-                ):
-                    return [
-                        checks.Error(
-                            "The value of '%s' cannot include the ManyToManyField "
-                            "'%s', because that field manually specifies a "
-                            "relationship model." % (label, field_name),
-                            obj=obj.__class__,
-                            id="admin.E013",
-                        )
-                    ]
-                else:
-                    return []
-
-    def _check_exclude(self, obj):
-        """Check that exclude is a sequence without duplicates."""
-
-        if obj.exclude is None:  # default value is None
-            return []
-        elif not isinstance(obj.exclude, (list, tuple)):
-            return must_be(
-                "a list or tuple", option="exclude", obj=obj, id="admin.E014"
-            )
-        elif len(obj.exclude) > len(set(obj.exclude)):
-            return [
-                checks.Error(
-                    "The value of 'exclude' contains duplicate field(s).",
-                    obj=obj.__class__,
-                    id="admin.E015",
-                )
-            ]
-        else:
-            return []
-
-    def _check_form(self, obj):
-        """Check that form subclasses BaseModelForm."""
-        if not _issubclass(obj.form, BaseModelForm):
-            return must_inherit_from(
-                parent="BaseModelForm", option="form", obj=obj, id="admin.E016"
-            )
-        else:
-            return []
-
-    def _check_filter_vertical(self, obj):
-        """Check that filter_vertical is a sequence of field names."""
-        if not isinstance(obj.filter_vertical, (list, tuple)):
-            return must_be(
-                "a list or tuple", option="filter_vertical", obj=obj, id="admin.E017"
-            )
-        else:
-            return list(
-                chain.from_iterable(
-                    self._check_filter_item(
-                        obj, field_name, "filter_vertical[%d]" % index
-                    )
-                    for index, field_name in enumerate(obj.filter_vertical)
-                )
-            )
-
-    def _check_filter_horizontal(self, obj):
-        """Check that filter_horizontal is a sequence of field names."""
-        if not isinstance(obj.filter_horizontal, (list, tuple)):
-            return must_be(
-                "a list or tuple", option="filter_horizontal", obj=obj, id="admin.E018"
-            )
-        else:
-            return list(
-                chain.from_iterable(
-                    self._check_filter_item(
-                        obj, field_name, "filter_horizontal[%d]" % index
-                    )
-                    for index, field_name in enumerate(obj.filter_horizontal)
-                )
-            )
-
-    def _check_filter_item(self, obj, field_name, label):
-        """Check one item of `filter_vertical` or `filter_horizontal`, i.e.
-        check that given field exists and is a ManyToManyField."""
-
-        try:
-            field = obj.model._meta.get_field(field_name)
-        except FieldDoesNotExist:
-            return refer_to_missing_field(
-                field=field_name, option=label, obj=obj, id="admin.E019"
-            )
-        else:
-            if not field.many_to_many or isinstance(field, models.ManyToManyRel):
-                return must_be(
-                    "a many-to-many field", option=label, obj=obj, id="admin.E020"
-                )
-            elif not field.remote_field.through._meta.auto_created:
-                return [
-                    checks.Error(
-                        f"The value of '{label}' cannot include the ManyToManyField "
-                        f"'{field_name}', because that field manually specifies a "
-                        f"relationship model.",
-                        obj=obj.__class__,
-                        id="admin.E013",
-                    )
-                ]
-            else:
-                return []
-
-    def _check_radio_fields(self, obj):
-        """Check that `radio_fields` is a dictionary."""
-        if not isinstance(obj.radio_fields, dict):
-            return must_be(
-                "a dictionary", option="radio_fields", obj=obj, id="admin.E021"
-            )
-        else:
-            return list(
-                chain.from_iterable(
-                    self._check_radio_fields_key(obj, field_name, "radio_fields")
-                    + self._check_radio_fields_value(
-                        obj, val, 'radio_fields["%s"]' % field_name
-                    )
-                    for field_name, val in obj.radio_fields.items()
-                )
-            )
-
-    def _check_radio_fields_key(self, obj, field_name, label):
-        """Check that a key of `radio_fields` dictionary is name of existing
-        field and that the field is a ForeignKey or has `choices` defined."""
-
-        try:
-            field = obj.model._meta.get_field(field_name)
-        except FieldDoesNotExist:
-            return refer_to_missing_field(
-                field=field_name, option=label, obj=obj, id="admin.E022"
-            )
-        else:
-            if not (isinstance(field, models.ForeignKey) or field.choices):
-                return [
-                    checks.Error(
-                        "The value of '%s' refers to '%s', which is not an "
-                        "instance of ForeignKey, and does not have a 'choices' "
-                        "definition." % (label, field_name),
-                        obj=obj.__class__,
-                        id="admin.E023",
-                    )
-                ]
-            else:
-                return []
-
-    def _check_radio_fields_value(self, obj, val, label):
-        """Check type of a value of `radio_fields` dictionary."""
-
-        from django.contrib.admin.options import HORIZONTAL, VERTICAL
-
-        if val not in (HORIZONTAL, VERTICAL):
-            return [
-                checks.Error(
-                    "The value of '%s' must be either admin.HORIZONTAL or "
-                    "admin.VERTICAL." % label,
-                    obj=obj.__class__,
-                    id="admin.E024",
-                )
-            ]
-        else:
-            return []
-
-    def _check_view_on_site_url(self, obj):
-        if not callable(obj.view_on_site) and not isinstance(obj.view_on_site, bool):
-            return [
-                checks.Error(
-                    "The value of 'view_on_site' must be a callable or a boolean "
-                    "value.",
-                    obj=obj.__class__,
-                    id="admin.E025",
-                )
-            ]
-        else:
-            return []
-
-    def _check_prepopulated_fields(self, obj):
-        """Check that `prepopulated_fields` is a dictionary containing allowed
-        field types."""
-        if not isinstance(obj.prepopulated_fields, dict):
-            return must_be(
-                "a dictionary", option="prepopulated_fields", obj=obj, id="admin.E026"
-            )
-        else:
-            return list(
-                chain.from_iterable(
-                    self._check_prepopulated_fields_key(
-                        obj, field_name, "prepopulated_fields"
-                    )
-                    + self._check_prepopulated_fields_value(
-                        obj, val, 'prepopulated_fields["%s"]' % field_name
-                    )
-                    for field_name, val in obj.prepopulated_fields.items()
-                )
-            )
-
-    def _check_prepopulated_fields_key(self, obj, field_name, label):
-        """Check a key of `prepopulated_fields` dictionary, i.e. check that it
-        is a name of existing field and the field is one of the allowed types.
-        """
-
-        try:
-            field = obj.model._meta.get_field(field_name)
-        except FieldDoesNotExist:
-            return refer_to_missing_field(
-                field=field_name, option=label, obj=obj, id="admin.E027"
-            )
-        else:
-            if isinstance(
-                field, (models.DateTimeField, models.ForeignKey, models.ManyToManyField)
-            ):
-                return [
-                    checks.Error(
-                        "The value of '%s' refers to '%s', which must not be a "
-                        "DateTimeField, a ForeignKey, a OneToOneField, or a "
-                        "ManyToManyField." % (label, field_name),
-                        obj=obj.__class__,
-                        id="admin.E028",
-                    )
-                ]
-            else:
-                return []
-
-    def _check_prepopulated_fields_value(self, obj, val, label):
-        """Check a value of `prepopulated_fields` dictionary, i.e. it's an
-        iterable of existing fields."""
-
-        if not isinstance(val, (list, tuple)):
-            return must_be("a list or tuple", option=label, obj=obj, id="admin.E029")
-        else:
-            return list(
-                chain.from_iterable(
-                    self._check_prepopulated_fields_value_item(
-                        obj, subfield_name, "%s[%r]" % (label, index)
-                    )
-                    for index, subfield_name in enumerate(val)
-                )
-            )
-
-    def _check_prepopulated_fields_value_item(self, obj, field_name, label):
-        """For `prepopulated_fields` equal to {"slug": ("title",)},
-        `field_name` is "title"."""
-
-        try:
-            obj.model._meta.get_field(field_name)
-        except FieldDoesNotExist:
-            return refer_to_missing_field(
-                field=field_name, option=label, obj=obj, id="admin.E030"
-            )
-        else:
-            return []
-
-    def _check_ordering(self, obj):
-        """Check that ordering refers to existing fields or is random."""
-
-        # ordering = None
-        if obj.ordering is None:  # The default value is None
-            return []
-        elif not isinstance(obj.ordering, (list, tuple)):
-            return must_be(
-                "a list or tuple", option="ordering", obj=obj, id="admin.E031"
-            )
-        else:
-            return list(
-                chain.from_iterable(
-                    self._check_ordering_item(obj, field_name, "ordering[%d]" % index)
-                    for index, field_name in enumerate(obj.ordering)
-                )
-            )
-
-    def _check_ordering_item(self, obj, field_name, label):
-        """Check that `ordering` refers to existing fields."""
-        if isinstance(field_name, (Combinable, models.OrderBy)):
-            if not isinstance(field_name, models.OrderBy):
-                field_name = field_name.asc()
-            if isinstance(field_name.expression, models.F):
-                field_name = field_name.expression.name
-            else:
-                return []
-        if field_name == "?" and len(obj.ordering) != 1:
-            return [
-                checks.Error(
-                    "The value of 'ordering' has the random ordering marker '?', "
-                    "but contains other fields as well.",
-                    hint='Either remove the "?", or remove the other fields.',
-                    obj=obj.__class__,
-                    id="admin.E032",
-                )
-            ]
-        elif field_name == "?":
-            return []
-        elif LOOKUP_SEP in field_name:
-            # Skip ordering in the format field1__field2 (FIXME: checking
-            # this format would be nice, but it's a little fiddly).
-            return []
-        else:
-            field_name = field_name.removeprefix("-")
-            if field_name == "pk":
-                return []
-            try:
-                obj.model._meta.get_field(field_name)
-            except FieldDoesNotExist:
-                return refer_to_missing_field(
-                    field=field_name, option=label, obj=obj, id="admin.E033"
-                )
-            else:
-                return []
-
-    def _check_readonly_fields(self, obj):
-        """Check that readonly_fields refers to proper attribute or field."""
-
-        if obj.readonly_fields == ():
-            return []
-        elif not isinstance(obj.readonly_fields, (list, tuple)):
-            return must_be(
-                "a list or tuple", option="readonly_fields", obj=obj, id="admin.E034"
-            )
-        else:
-            return list(
-                chain.from_iterable(
-                    self._check_readonly_fields_item(
-                        obj, field_name, "readonly_fields[%d]" % index
-                    )
-                    for index, field_name in enumerate(obj.readonly_fields)
-                )
-            )
-
-    def _check_readonly_fields_item(self, obj, field_name, label):
-        if callable(field_name):
-            return []
-        elif hasattr(obj, field_name):
-            return []
-        elif hasattr(obj.model, field_name):
-            return []
-        else:
-            try:
-                obj.model._meta.get_field(field_name)
-            except FieldDoesNotExist:
-                return [
-                    checks.Error(
-                        "The value of '%s' refers to '%s', which is not a callable, "
-                        "an attribute of '%s', or an attribute of '%s'."
-                        % (
-                            label,
-                            field_name,
-                            obj.__class__.__name__,
-                            obj.model._meta.label,
-                        ),
-                        obj=obj.__class__,
-                        id="admin.E035",
-                    )
-                ]
-            else:
-                return []
-
-
-class ModelAdminChecks(BaseModelAdminChecks):
-    def check(self, admin_obj, **kwargs):
-        return [
-            *super().check(admin_obj),
-            *self._check_save_as(admin_obj),
-            *self._check_save_on_top(admin_obj),
-            *self._check_inlines(admin_obj),
-            *self._check_list_display(admin_obj),
-            *self._check_list_display_links(admin_obj),
-            *self._check_list_filter(admin_obj),
-            *self._check_list_select_related(admin_obj),
-            *self._check_list_per_page(admin_obj),
-            *self._check_list_max_show_all(admin_obj),
-            *self._check_list_editable(admin_obj),
-            *self._check_search_fields(admin_obj),
-            *self._check_date_hierarchy(admin_obj),
-            *self._check_actions(admin_obj),
-        ]
-
-    def _check_save_as(self, obj):
-        """Check save_as is a boolean."""
-
-        if not isinstance(obj.save_as, bool):
-            return must_be("a boolean", option="save_as", obj=obj, id="admin.E101")
-        else:
-            return []
-
-    def _check_save_on_top(self, obj):
-        """Check save_on_top is a boolean."""
-
-        if not isinstance(obj.save_on_top, bool):
-            return must_be("a boolean", option="save_on_top", obj=obj, id="admin.E102")
-        else:
-            return []
-
-    def _check_inlines(self, obj):
-        """Check all inline model admin classes."""
-
-        if not isinstance(obj.inlines, (list, tuple)):
-            return must_be(
-                "a list or tuple", option="inlines", obj=obj, id="admin.E103"
-            )
-        else:
-            return list(
-                chain.from_iterable(
-                    self._check_inlines_item(obj, item, "inlines[%d]" % index)
-                    for index, item in enumerate(obj.inlines)
-                )
-            )
-
-    def _check_inlines_item(self, obj, inline, label):
-        """Check one inline model admin."""
-        try:
-            inline_label = inline.__module__ + "." + inline.__name__
-        except AttributeError:
-            return [
-                checks.Error(
-                    "'%s' must inherit from 'InlineModelAdmin'." % obj,
-                    obj=obj.__class__,
-                    id="admin.E104",
-                )
-            ]
-
-        from django.contrib.admin.options import InlineModelAdmin
-
-        if not _issubclass(inline, InlineModelAdmin):
-            return [
-                checks.Error(
-                    "'%s' must inherit from 'InlineModelAdmin'." % inline_label,
-                    obj=obj.__class__,
-                    id="admin.E104",
-                )
-            ]
-        elif not inline.model:
-            return [
-                checks.Error(
-                    "'%s' must have a 'model' attribute." % inline_label,
-                    obj=obj.__class__,
-                    id="admin.E105",
-                )
-            ]
-        elif not _issubclass(inline.model, models.Model):
-            return must_be(
-                "a Model", option="%s.model" % inline_label, obj=obj, id="admin.E106"
-            )
-        else:
-            return inline(obj.model, obj.admin_site).check()
-
-    def _check_list_display(self, obj):
-        """Check that list_display only contains fields or usable attributes."""
-
-        if not isinstance(obj.list_display, (list, tuple)):
-            return must_be(
-                "a list or tuple", option="list_display", obj=obj, id="admin.E107"
-            )
-        else:
-            return list(
-                chain.from_iterable(
-                    self._check_list_display_item(obj, item, "list_display[%d]" % index)
-                    for index, item in enumerate(obj.list_display)
-                )
-            )
-
-    def _check_list_display_item(self, obj, item, label):
-        if callable(item):
-            return []
-        elif hasattr(obj, item):
-            return []
-        try:
-            field = obj.model._meta.get_field(item)
-        except FieldDoesNotExist:
-            try:
-                field = getattr(obj.model, item)
-            except AttributeError:
-                try:
-                    field = get_fields_from_path(obj.model, item)[-1]
-                except (FieldDoesNotExist, NotRelationField):
-                    return [
-                        checks.Error(
-                            f"The value of '{label}' refers to '{item}', which is not "
-                            f"a callable or attribute of '{obj.__class__.__name__}', "
-                            "or an attribute, method, or field on "
-                            f"'{obj.model._meta.label}'.",
-                            obj=obj.__class__,
-                            id="admin.E108",
-                        )
-                    ]
-        if (
-            getattr(field, "is_relation", False)
-            and (field.many_to_many or field.one_to_many)
-        ) or (getattr(field, "rel", None) and field.rel.field.many_to_one):
-            return [
-                checks.Error(
-                    f"The value of '{label}' must not be a many-to-many field or a "
-                    f"reverse foreign key.",
-                    obj=obj.__class__,
-                    id="admin.E109",
-                )
-            ]
-        return []
-
-    def _check_list_display_links(self, obj):
-        """Check that list_display_links is a unique subset of list_display."""
-        from django.contrib.admin.options import ModelAdmin
-
-        if obj.list_display_links is None:
-            return []
-        elif not isinstance(obj.list_display_links, (list, tuple)):
-            return must_be(
-                "a list, a tuple, or None",
-                option="list_display_links",
-                obj=obj,
-                id="admin.E110",
-            )
-        # Check only if ModelAdmin.get_list_display() isn't overridden.
-        elif obj.get_list_display.__func__ is ModelAdmin.get_list_display:
-            return list(
-                chain.from_iterable(
-                    self._check_list_display_links_item(
-                        obj, field_name, "list_display_links[%d]" % index
-                    )
-                    for index, field_name in enumerate(obj.list_display_links)
-                )
-            )
-        return []
-
-    def _check_list_display_links_item(self, obj, field_name, label):
-        if field_name not in obj.list_display:
-            return [
-                checks.Error(
-                    "The value of '%s' refers to '%s', which is not defined in "
-                    "'list_display'." % (label, field_name),
-                    obj=obj.__class__,
-                    id="admin.E111",
-                )
-            ]
-        else:
-            return []
-
-    def _check_list_filter(self, obj):
-        if not isinstance(obj.list_filter, (list, tuple)):
-            return must_be(
-                "a list or tuple", option="list_filter", obj=obj, id="admin.E112"
-            )
-        else:
-            return list(
-                chain.from_iterable(
-                    self._check_list_filter_item(obj, item, "list_filter[%d]" % index)
-                    for index, item in enumerate(obj.list_filter)
-                )
-            )
-
-    def _check_list_filter_item(self, obj, item, label):
-        """
-        Check one item of `list_filter`, i.e. check if it is one of three options:
-        1. 'field' -- a basic field filter, possibly w/ relationships (e.g.
-           'field__rel')
-        2. ('field', SomeFieldListFilter) - a field-based list filter class
-        3. SomeListFilter - a non-field list filter class
-        """
-        from django.contrib.admin import FieldListFilter, ListFilter
-
-        if callable(item) and not isinstance(item, models.Field):
-            # If item is option 3, it should be a ListFilter...
-            if not _issubclass(item, ListFilter):
-                return must_inherit_from(
-                    parent="ListFilter", option=label, obj=obj, id="admin.E113"
-                )
-            # ...  but not a FieldListFilter.
-            elif issubclass(item, FieldListFilter):
-                return [
-                    checks.Error(
-                        "The value of '%s' must not inherit from 'FieldListFilter'."
-                        % label,
-                        obj=obj.__class__,
-                        id="admin.E114",
-                    )
-                ]
-            else:
-                return []
-        elif isinstance(item, (tuple, list)):
-            # item is option #2
-            field, list_filter_class = item
-            if not _issubclass(list_filter_class, FieldListFilter):
-                return must_inherit_from(
-                    parent="FieldListFilter",
-                    option="%s[1]" % label,
-                    obj=obj,
-                    id="admin.E115",
-                )
-            else:
-                return []
-        else:
-            # item is option #1
-            field = item
-
-            # Validate the field string
-            try:
-                get_fields_from_path(obj.model, field)
-            except (NotRelationField, FieldDoesNotExist):
-                return [
-                    checks.Error(
-                        "The value of '%s' refers to '%s', which does not refer to a "
-                        "Field." % (label, field),
-                        obj=obj.__class__,
-                        id="admin.E116",
-                    )
-                ]
-            else:
-                return []
-
-    def _check_list_select_related(self, obj):
-        """Check that list_select_related is a boolean, a list or a tuple."""
-
-        if not isinstance(obj.list_select_related, (bool, list, tuple)):
-            return must_be(
-                "a boolean, tuple or list",
-                option="list_select_related",
-                obj=obj,
-                id="admin.E117",
-            )
-        else:
-            return []
-
-    def _check_list_per_page(self, obj):
-        """Check that list_per_page is an integer."""
-
-        if not isinstance(obj.list_per_page, int):
-            return must_be(
-                "an integer", option="list_per_page", obj=obj, id="admin.E118"
-            )
-        else:
-            return []
-
-    def _check_list_max_show_all(self, obj):
-        """Check that list_max_show_all is an integer."""
-
-        if not isinstance(obj.list_max_show_all, int):
-            return must_be(
-                "an integer", option="list_max_show_all", obj=obj, id="admin.E119"
-            )
-        else:
-            return []
-
-    def _check_list_editable(self, obj):
-        """Check that list_editable is a sequence of editable fields from
-        list_display without first element."""
-
-        if not isinstance(obj.list_editable, (list, tuple)):
-            return must_be(
-                "a list or tuple", option="list_editable", obj=obj, id="admin.E120"
-            )
-        else:
-            return list(
-                chain.from_iterable(
-                    self._check_list_editable_item(
-                        obj, item, "list_editable[%d]" % index
-                    )
-                    for index, item in enumerate(obj.list_editable)
-                )
-            )
-
-    def _check_list_editable_item(self, obj, field_name, label):
-        try:
-            field = obj.model._meta.get_field(field_name)
-        except FieldDoesNotExist:
-            return refer_to_missing_field(
-                field=field_name, option=label, obj=obj, id="admin.E121"
-            )
-        else:
-            if field_name not in obj.list_display:
-                return [
-                    checks.Error(
-                        "The value of '%s' refers to '%s', which is not "
-                        "contained in 'list_display'." % (label, field_name),
-                        obj=obj.__class__,
-                        id="admin.E122",
-                    )
-                ]
-            elif obj.list_display_links and field_name in obj.list_display_links:
-                return [
-                    checks.Error(
-                        "The value of '%s' cannot be in both 'list_editable' and "
-                        "'list_display_links'." % field_name,
-                        obj=obj.__class__,
-                        id="admin.E123",
-                    )
-                ]
-            # If list_display[0] is in list_editable, check that
-            # list_display_links is set. See #22792 and #26229 for use cases.
-            elif (
-                obj.list_display[0] == field_name
-                and not obj.list_display_links
-                and obj.list_display_links is not None
-            ):
-                return [
-                    checks.Error(
-                        "The value of '%s' refers to the first field in 'list_display' "
-                        "('%s'), which cannot be used unless 'list_display_links' is "
-                        "set." % (label, obj.list_display[0]),
-                        obj=obj.__class__,
-                        id="admin.E124",
-                    )
-                ]
-            elif not field.editable or field.primary_key:
-                return [
-                    checks.Error(
-                        "The value of '%s' refers to '%s', which is not editable "
-                        "through the admin." % (label, field_name),
-                        obj=obj.__class__,
-                        id="admin.E125",
-                    )
-                ]
-            else:
-                return []
-
-    def _check_search_fields(self, obj):
-        """Check search_fields is a sequence."""
-
-        if not isinstance(obj.search_fields, (list, tuple)):
-            return must_be(
-                "a list or tuple", option="search_fields", obj=obj, id="admin.E126"
-            )
-        else:
-            return []
-
-    def _check_date_hierarchy(self, obj):
-        """Check that date_hierarchy refers to DateField or DateTimeField."""
-
-        if obj.date_hierarchy is None:
-            return []
-        else:
-            try:
-                field = get_fields_from_path(obj.model, obj.date_hierarchy)[-1]
-            except (NotRelationField, FieldDoesNotExist):
-                return [
-                    checks.Error(
-                        "The value of 'date_hierarchy' refers to '%s', which "
-                        "does not refer to a Field." % obj.date_hierarchy,
-                        obj=obj.__class__,
-                        id="admin.E127",
-                    )
-                ]
-            else:
-                if field.get_internal_type() not in {"DateField", "DateTimeField"}:
-                    return must_be(
-                        "a DateField or DateTimeField",
-                        option="date_hierarchy",
-                        obj=obj,
-                        id="admin.E128",
-                    )
-                else:
-                    return []
-
-    def _check_actions(self, obj):
-        errors = []
-        actions = obj._get_base_actions()
-
-        # Actions with an allowed_permission attribute require the ModelAdmin
-        # to implement a has_<perm>_permission() method for each permission.
-        for func, name, _ in actions:
-            if not hasattr(func, "allowed_permissions"):
-                continue
-            for permission in func.allowed_permissions:
-                method_name = "has_%s_permission" % permission
-                if not hasattr(obj, method_name):
-                    errors.append(
-                        checks.Error(
-                            "%s must define a %s() method for the %s action."
-                            % (
-                                obj.__class__.__name__,
-                                method_name,
-                                func.__name__,
-                            ),
-                            obj=obj.__class__,
-                            id="admin.E129",
-                        )
-                    )
-        # Names need to be unique.
-        names = collections.Counter(name for _, name, _ in actions)
-        for name, count in names.items():
-            if count > 1:
-                errors.append(
-                    checks.Error(
-                        "__name__ attributes of actions defined in %s must be "
-                        "unique. Name %r is not unique."
-                        % (
-                            obj.__class__.__name__,
-                            name,
-                        ),
-                        obj=obj.__class__,
-                        id="admin.E130",
-                    )
-                )
-        return errors
-
-
-class InlineModelAdminChecks(BaseModelAdminChecks):
-    def check(self, inline_obj, **kwargs):
-        parent_model = inline_obj.parent_model
-        return [
-            *super().check(inline_obj),
-            *self._check_relation(inline_obj, parent_model),
-            *self._check_exclude_of_parent_model(inline_obj, parent_model),
-            *self._check_extra(inline_obj),
-            *self._check_max_num(inline_obj),
-            *self._check_min_num(inline_obj),
-            *self._check_formset(inline_obj),
-        ]
-
-    def _check_exclude_of_parent_model(self, obj, parent_model):
-        # Do not perform more specific checks if the base checks result in an
-        # error.
-        errors = super()._check_exclude(obj)
-        if errors:
-            return []
-
-        # Skip if `fk_name` is invalid.
-        if self._check_relation(obj, parent_model):
-            return []
-
-        if obj.exclude is None:
-            return []
-
-        fk = _get_foreign_key(parent_model, obj.model, fk_name=obj.fk_name)
-        if fk.name in obj.exclude:
-            return [
-                checks.Error(
-                    "Cannot exclude the field '%s', because it is the foreign key "
-                    "to the parent model '%s'."
-                    % (
-                        fk.name,
-                        parent_model._meta.label,
-                    ),
-                    obj=obj.__class__,
-                    id="admin.E201",
-                )
-            ]
-        else:
-            return []
-
-    def _check_relation(self, obj, parent_model):
-        try:
-            _get_foreign_key(parent_model, obj.model, fk_name=obj.fk_name)
-        except ValueError as e:
-            return [checks.Error(e.args[0], obj=obj.__class__, id="admin.E202")]
-        else:
-            return []
-
-    def _check_extra(self, obj):
-        """Check that extra is an integer."""
-
-        if not isinstance(obj.extra, int):
-            return must_be("an integer", option="extra", obj=obj, id="admin.E203")
-        else:
-            return []
-
-    def _check_max_num(self, obj):
-        """Check that max_num is an integer."""
-
-        if obj.max_num is None:
-            return []
-        elif not isinstance(obj.max_num, int):
-            return must_be("an integer", option="max_num", obj=obj, id="admin.E204")
-        else:
-            return []
-
-    def _check_min_num(self, obj):
-        """Check that min_num is an integer."""
-
-        if obj.min_num is None:
-            return []
-        elif not isinstance(obj.min_num, int):
-            return must_be("an integer", option="min_num", obj=obj, id="admin.E205")
-        else:
-            return []
-
-    def _check_formset(self, obj):
-        """Check formset is a subclass of BaseModelFormSet."""
-
-        if not _issubclass(obj.formset, BaseModelFormSet):
-            return must_inherit_from(
-                parent="BaseModelFormSet", option="formset", obj=obj, id="admin.E206"
-            )
-        else:
-            return []
-
-
-def must_be(type, option, obj, id):
-    return [
-        checks.Error(
-            "The value of '%s' must be %s." % (option, type),
-            obj=obj.__class__,
-            id=id,
-        ),
-    ]
-
-
-def must_inherit_from(parent, option, obj, id):
-    return [
-        checks.Error(
-            "The value of '%s' must inherit from '%s'." % (option, parent),
-            obj=obj.__class__,
-            id=id,
-        ),
-    ]
-
-
-def refer_to_missing_field(field, option, obj, id):
-    return [
-        checks.Error(
-            "The value of '%s' refers to '%s', which is not a field of '%s'."
-            % (option, field, obj.model._meta.label),
-            obj=obj.__class__,
-            id=id,
-        ),
-    ]

+ 0 - 0
static/admin/static/admin/css/autocomplete.css → static/admin/css/autocomplete.css


+ 0 - 0
static/admin/static/admin/css/base.css → static/admin/css/base.css


+ 0 - 0
static/admin/static/admin/css/changelists.css → static/admin/css/changelists.css


+ 0 - 0
static/admin/static/admin/css/dark_mode.css → static/admin/css/dark_mode.css


+ 0 - 0
static/admin/static/admin/css/dashboard.css → static/admin/css/dashboard.css


+ 0 - 0
static/admin/static/admin/css/forms.css → static/admin/css/forms.css


+ 0 - 0
static/admin/static/admin/css/login.css → static/admin/css/login.css


+ 0 - 0
static/admin/static/admin/css/nav_sidebar.css → static/admin/css/nav_sidebar.css


+ 0 - 0
static/admin/static/admin/css/responsive.css → static/admin/css/responsive.css


+ 0 - 0
static/admin/static/admin/css/responsive_rtl.css → static/admin/css/responsive_rtl.css


+ 0 - 0
static/admin/static/admin/css/rtl.css → static/admin/css/rtl.css


+ 0 - 0
static/admin/static/admin/css/unusable_password_field.css → static/admin/css/unusable_password_field.css


+ 0 - 0
static/admin/static/admin/css/vendor/select2/LICENSE-SELECT2.md → static/admin/css/vendor/select2/LICENSE-SELECT2.md


+ 0 - 0
static/admin/static/admin/css/vendor/select2/select2.css → static/admin/css/vendor/select2/select2.css


+ 0 - 0
static/admin/static/admin/css/vendor/select2/select2.min.css → static/admin/css/vendor/select2/select2.min.css


+ 0 - 0
static/admin/static/admin/css/widgets.css → static/admin/css/widgets.css


+ 0 - 111
static/admin/decorators.py

@@ -1,111 +0,0 @@
-def action(function=None, *, permissions=None, description=None):
-    """
-    Conveniently add attributes to an action function::
-
-        @admin.action(
-            permissions=['publish'],
-            description='Mark selected stories as published',
-        )
-        def make_published(self, request, queryset):
-            queryset.update(status='p')
-
-    This is equivalent to setting some attributes (with the original, longer
-    names) on the function directly::
-
-        def make_published(self, request, queryset):
-            queryset.update(status='p')
-        make_published.allowed_permissions = ['publish']
-        make_published.short_description = 'Mark selected stories as published'
-    """
-
-    def decorator(func):
-        if permissions is not None:
-            func.allowed_permissions = permissions
-        if description is not None:
-            func.short_description = description
-        return func
-
-    if function is None:
-        return decorator
-    else:
-        return decorator(function)
-
-
-def display(
-    function=None, *, boolean=None, ordering=None, description=None, empty_value=None
-):
-    """
-    Conveniently add attributes to a display function::
-
-        @admin.display(
-            boolean=True,
-            ordering='-publish_date',
-            description='Is Published?',
-        )
-        def is_published(self, obj):
-            return obj.publish_date is not None
-
-    This is equivalent to setting some attributes (with the original, longer
-    names) on the function directly::
-
-        def is_published(self, obj):
-            return obj.publish_date is not None
-        is_published.boolean = True
-        is_published.admin_order_field = '-publish_date'
-        is_published.short_description = 'Is Published?'
-    """
-
-    def decorator(func):
-        if boolean is not None and empty_value is not None:
-            raise ValueError(
-                "The boolean and empty_value arguments to the @display "
-                "decorator are mutually exclusive."
-            )
-        if boolean is not None:
-            func.boolean = boolean
-        if ordering is not None:
-            func.admin_order_field = ordering
-        if description is not None:
-            func.short_description = description
-        if empty_value is not None:
-            func.empty_value_display = empty_value
-        return func
-
-    if function is None:
-        return decorator
-    else:
-        return decorator(function)
-
-
-def register(*models, site=None):
-    """
-    Register the given model(s) classes and wrapped ModelAdmin class with
-    admin site:
-
-    @register(Author)
-    class AuthorAdmin(admin.ModelAdmin):
-        pass
-
-    The `site` kwarg is an admin site to use instead of the default admin site.
-    """
-    from django.contrib.admin import ModelAdmin
-    from django.contrib.admin.sites import AdminSite
-    from django.contrib.admin.sites import site as default_site
-
-    def _model_admin_wrapper(admin_class):
-        if not models:
-            raise ValueError("At least one model must be passed to register.")
-
-        admin_site = site or default_site
-
-        if not isinstance(admin_site, AdminSite):
-            raise ValueError("site must subclass AdminSite")
-
-        if not issubclass(admin_class, ModelAdmin):
-            raise ValueError("Wrapped class must subclass ModelAdmin.")
-
-        admin_site.register(models, admin_class=admin_class)
-
-        return admin_class
-
-    return _model_admin_wrapper

+ 0 - 25
static/admin/exceptions.py

@@ -1,25 +0,0 @@
-from django.core.exceptions import SuspiciousOperation
-
-
-class DisallowedModelAdminLookup(SuspiciousOperation):
-    """Invalid filter was passed to admin view via URL querystring"""
-
-    pass
-
-
-class DisallowedModelAdminToField(SuspiciousOperation):
-    """Invalid to_field was passed to admin view via URL query string"""
-
-    pass
-
-
-class AlreadyRegistered(Exception):
-    """The model is already registered."""
-
-    pass
-
-
-class NotRegistered(Exception):
-    """The model is not registered."""
-
-    pass

+ 0 - 716
static/admin/filters.py

@@ -1,716 +0,0 @@
-"""
-This encapsulates the logic for displaying filters in the Django admin.
-Filters are specified in models with the "list_filter" option.
-
-Each filter subclass knows how to display a filter for a field that passes a
-certain test -- e.g. being a DateField or ForeignKey.
-"""
-
-import datetime
-
-from django.contrib.admin.exceptions import NotRegistered
-from django.contrib.admin.options import IncorrectLookupParameters
-from django.contrib.admin.utils import (
-    build_q_object_from_lookup_parameters,
-    get_last_value_from_parameters,
-    get_model_from_relation,
-    prepare_lookup_value,
-    reverse_field_path,
-)
-from django.core.exceptions import ImproperlyConfigured, ValidationError
-from django.db import models
-from django.utils import timezone
-from django.utils.translation import gettext_lazy as _
-
-
-class ListFilter:
-    title = None  # Human-readable title to appear in the right sidebar.
-    template = "admin/filter.html"
-
-    def __init__(self, request, params, model, model_admin):
-        self.request = request
-        # This dictionary will eventually contain the request's query string
-        # parameters actually used by this filter.
-        self.used_parameters = {}
-        if self.title is None:
-            raise ImproperlyConfigured(
-                "The list filter '%s' does not specify a 'title'."
-                % self.__class__.__name__
-            )
-
-    def has_output(self):
-        """
-        Return True if some choices would be output for this filter.
-        """
-        raise NotImplementedError(
-            "subclasses of ListFilter must provide a has_output() method"
-        )
-
-    def choices(self, changelist):
-        """
-        Return choices ready to be output in the template.
-
-        `changelist` is the ChangeList to be displayed.
-        """
-        raise NotImplementedError(
-            "subclasses of ListFilter must provide a choices() method"
-        )
-
-    def queryset(self, request, queryset):
-        """
-        Return the filtered queryset.
-        """
-        raise NotImplementedError(
-            "subclasses of ListFilter must provide a queryset() method"
-        )
-
-    def expected_parameters(self):
-        """
-        Return the list of parameter names that are expected from the
-        request's query string and that will be used by this filter.
-        """
-        raise NotImplementedError(
-            "subclasses of ListFilter must provide an expected_parameters() method"
-        )
-
-
-class FacetsMixin:
-    def get_facet_counts(self, pk_attname, filtered_qs):
-        raise NotImplementedError(
-            "subclasses of FacetsMixin must provide a get_facet_counts() method."
-        )
-
-    def get_facet_queryset(self, changelist):
-        filtered_qs = changelist.get_queryset(
-            self.request, exclude_parameters=self.expected_parameters()
-        )
-        return filtered_qs.aggregate(
-            **self.get_facet_counts(changelist.pk_attname, filtered_qs)
-        )
-
-
-class SimpleListFilter(FacetsMixin, ListFilter):
-    # The parameter that should be used in the query string for that filter.
-    parameter_name = None
-
-    def __init__(self, request, params, model, model_admin):
-        super().__init__(request, params, model, model_admin)
-        if self.parameter_name is None:
-            raise ImproperlyConfigured(
-                "The list filter '%s' does not specify a 'parameter_name'."
-                % self.__class__.__name__
-            )
-        if self.parameter_name in params:
-            value = params.pop(self.parameter_name)
-            self.used_parameters[self.parameter_name] = value[-1]
-        lookup_choices = self.lookups(request, model_admin)
-        if lookup_choices is None:
-            lookup_choices = ()
-        self.lookup_choices = list(lookup_choices)
-
-    def has_output(self):
-        return len(self.lookup_choices) > 0
-
-    def value(self):
-        """
-        Return the value (in string format) provided in the request's
-        query string for this filter, if any, or None if the value wasn't
-        provided.
-        """
-        return self.used_parameters.get(self.parameter_name)
-
-    def lookups(self, request, model_admin):
-        """
-        Must be overridden to return a list of tuples (value, verbose value)
-        """
-        raise NotImplementedError(
-            "The SimpleListFilter.lookups() method must be overridden to "
-            "return a list of tuples (value, verbose value)."
-        )
-
-    def expected_parameters(self):
-        return [self.parameter_name]
-
-    def get_facet_counts(self, pk_attname, filtered_qs):
-        original_value = self.used_parameters.get(self.parameter_name)
-        counts = {}
-        for i, choice in enumerate(self.lookup_choices):
-            self.used_parameters[self.parameter_name] = choice[0]
-            lookup_qs = self.queryset(self.request, filtered_qs)
-            if lookup_qs is not None:
-                counts[f"{i}__c"] = models.Count(
-                    pk_attname,
-                    filter=models.Q(pk__in=lookup_qs),
-                )
-        self.used_parameters[self.parameter_name] = original_value
-        return counts
-
-    def choices(self, changelist):
-        add_facets = changelist.add_facets
-        facet_counts = self.get_facet_queryset(changelist) if add_facets else None
-        yield {
-            "selected": self.value() is None,
-            "query_string": changelist.get_query_string(remove=[self.parameter_name]),
-            "display": _("All"),
-        }
-        for i, (lookup, title) in enumerate(self.lookup_choices):
-            if add_facets:
-                if (count := facet_counts.get(f"{i}__c", -1)) != -1:
-                    title = f"{title} ({count})"
-                else:
-                    title = f"{title} (-)"
-            yield {
-                "selected": self.value() == str(lookup),
-                "query_string": changelist.get_query_string(
-                    {self.parameter_name: lookup}
-                ),
-                "display": title,
-            }
-
-
-class FieldListFilter(FacetsMixin, ListFilter):
-    _field_list_filters = []
-    _take_priority_index = 0
-    list_separator = ","
-
-    def __init__(self, field, request, params, model, model_admin, field_path):
-        self.field = field
-        self.field_path = field_path
-        self.title = getattr(field, "verbose_name", field_path)
-        super().__init__(request, params, model, model_admin)
-        for p in self.expected_parameters():
-            if p in params:
-                value = params.pop(p)
-                self.used_parameters[p] = prepare_lookup_value(
-                    p, value, self.list_separator
-                )
-
-    def has_output(self):
-        return True
-
-    def queryset(self, request, queryset):
-        try:
-            q_object = build_q_object_from_lookup_parameters(self.used_parameters)
-            return queryset.filter(q_object)
-        except (ValueError, ValidationError) as e:
-            # Fields may raise a ValueError or ValidationError when converting
-            # the parameters to the correct type.
-            raise IncorrectLookupParameters(e)
-
-    @classmethod
-    def register(cls, test, list_filter_class, take_priority=False):
-        if take_priority:
-            # This is to allow overriding the default filters for certain types
-            # of fields with some custom filters. The first found in the list
-            # is used in priority.
-            cls._field_list_filters.insert(
-                cls._take_priority_index, (test, list_filter_class)
-            )
-            cls._take_priority_index += 1
-        else:
-            cls._field_list_filters.append((test, list_filter_class))
-
-    @classmethod
-    def create(cls, field, request, params, model, model_admin, field_path):
-        for test, list_filter_class in cls._field_list_filters:
-            if test(field):
-                return list_filter_class(
-                    field, request, params, model, model_admin, field_path=field_path
-                )
-
-
-class RelatedFieldListFilter(FieldListFilter):
-    def __init__(self, field, request, params, model, model_admin, field_path):
-        other_model = get_model_from_relation(field)
-        self.lookup_kwarg = "%s__%s__exact" % (field_path, field.target_field.name)
-        self.lookup_kwarg_isnull = "%s__isnull" % field_path
-        self.lookup_val = params.get(self.lookup_kwarg)
-        self.lookup_val_isnull = get_last_value_from_parameters(
-            params, self.lookup_kwarg_isnull
-        )
-        super().__init__(field, request, params, model, model_admin, field_path)
-        self.lookup_choices = self.field_choices(field, request, model_admin)
-        if hasattr(field, "verbose_name"):
-            self.lookup_title = field.verbose_name
-        else:
-            self.lookup_title = other_model._meta.verbose_name
-        self.title = self.lookup_title
-        self.empty_value_display = model_admin.get_empty_value_display()
-
-    @property
-    def include_empty_choice(self):
-        """
-        Return True if a "(None)" choice should be included, which filters
-        out everything except empty relationships.
-        """
-        return self.field.null or (self.field.is_relation and self.field.many_to_many)
-
-    def has_output(self):
-        if self.include_empty_choice:
-            extra = 1
-        else:
-            extra = 0
-        return len(self.lookup_choices) + extra > 1
-
-    def expected_parameters(self):
-        return [self.lookup_kwarg, self.lookup_kwarg_isnull]
-
-    def field_admin_ordering(self, field, request, model_admin):
-        """
-        Return the model admin's ordering for related field, if provided.
-        """
-        try:
-            related_admin = model_admin.admin_site.get_model_admin(
-                field.remote_field.model
-            )
-        except NotRegistered:
-            return ()
-        else:
-            return related_admin.get_ordering(request)
-
-    def field_choices(self, field, request, model_admin):
-        ordering = self.field_admin_ordering(field, request, model_admin)
-        return field.get_choices(include_blank=False, ordering=ordering)
-
-    def get_facet_counts(self, pk_attname, filtered_qs):
-        counts = {
-            f"{pk_val}__c": models.Count(
-                pk_attname, filter=models.Q(**{self.lookup_kwarg: pk_val})
-            )
-            for pk_val, _ in self.lookup_choices
-        }
-        if self.include_empty_choice:
-            counts["__c"] = models.Count(
-                pk_attname, filter=models.Q(**{self.lookup_kwarg_isnull: True})
-            )
-        return counts
-
-    def choices(self, changelist):
-        add_facets = changelist.add_facets
-        facet_counts = self.get_facet_queryset(changelist) if add_facets else None
-        yield {
-            "selected": self.lookup_val is None and not self.lookup_val_isnull,
-            "query_string": changelist.get_query_string(
-                remove=[self.lookup_kwarg, self.lookup_kwarg_isnull]
-            ),
-            "display": _("All"),
-        }
-        count = None
-        for pk_val, val in self.lookup_choices:
-            if add_facets:
-                count = facet_counts[f"{pk_val}__c"]
-                val = f"{val} ({count})"
-            yield {
-                "selected": self.lookup_val is not None
-                and str(pk_val) in self.lookup_val,
-                "query_string": changelist.get_query_string(
-                    {self.lookup_kwarg: pk_val}, [self.lookup_kwarg_isnull]
-                ),
-                "display": val,
-            }
-        empty_title = self.empty_value_display
-        if self.include_empty_choice:
-            if add_facets:
-                count = facet_counts["__c"]
-                empty_title = f"{empty_title} ({count})"
-            yield {
-                "selected": bool(self.lookup_val_isnull),
-                "query_string": changelist.get_query_string(
-                    {self.lookup_kwarg_isnull: "True"}, [self.lookup_kwarg]
-                ),
-                "display": empty_title,
-            }
-
-
-FieldListFilter.register(lambda f: f.remote_field, RelatedFieldListFilter)
-
-
-class BooleanFieldListFilter(FieldListFilter):
-    def __init__(self, field, request, params, model, model_admin, field_path):
-        self.lookup_kwarg = "%s__exact" % field_path
-        self.lookup_kwarg2 = "%s__isnull" % field_path
-        self.lookup_val = get_last_value_from_parameters(params, self.lookup_kwarg)
-        self.lookup_val2 = get_last_value_from_parameters(params, self.lookup_kwarg2)
-        super().__init__(field, request, params, model, model_admin, field_path)
-        if (
-            self.used_parameters
-            and self.lookup_kwarg in self.used_parameters
-            and self.used_parameters[self.lookup_kwarg] in ("1", "0")
-        ):
-            self.used_parameters[self.lookup_kwarg] = bool(
-                int(self.used_parameters[self.lookup_kwarg])
-            )
-
-    def expected_parameters(self):
-        return [self.lookup_kwarg, self.lookup_kwarg2]
-
-    def get_facet_counts(self, pk_attname, filtered_qs):
-        return {
-            "true__c": models.Count(
-                pk_attname, filter=models.Q(**{self.field_path: True})
-            ),
-            "false__c": models.Count(
-                pk_attname, filter=models.Q(**{self.field_path: False})
-            ),
-            "null__c": models.Count(
-                pk_attname, filter=models.Q(**{self.lookup_kwarg2: True})
-            ),
-        }
-
-    def choices(self, changelist):
-        field_choices = dict(self.field.flatchoices)
-        add_facets = changelist.add_facets
-        facet_counts = self.get_facet_queryset(changelist) if add_facets else None
-        for lookup, title, count_field in (
-            (None, _("All"), None),
-            ("1", field_choices.get(True, _("Yes")), "true__c"),
-            ("0", field_choices.get(False, _("No")), "false__c"),
-        ):
-            if add_facets:
-                if count_field is not None:
-                    count = facet_counts[count_field]
-                    title = f"{title} ({count})"
-            yield {
-                "selected": self.lookup_val == lookup and not self.lookup_val2,
-                "query_string": changelist.get_query_string(
-                    {self.lookup_kwarg: lookup}, [self.lookup_kwarg2]
-                ),
-                "display": title,
-            }
-        if self.field.null:
-            display = field_choices.get(None, _("Unknown"))
-            if add_facets:
-                count = facet_counts["null__c"]
-                display = f"{display} ({count})"
-            yield {
-                "selected": self.lookup_val2 == "True",
-                "query_string": changelist.get_query_string(
-                    {self.lookup_kwarg2: "True"}, [self.lookup_kwarg]
-                ),
-                "display": display,
-            }
-
-
-FieldListFilter.register(
-    lambda f: isinstance(f, models.BooleanField), BooleanFieldListFilter
-)
-
-
-class ChoicesFieldListFilter(FieldListFilter):
-    def __init__(self, field, request, params, model, model_admin, field_path):
-        self.lookup_kwarg = "%s__exact" % field_path
-        self.lookup_kwarg_isnull = "%s__isnull" % field_path
-        self.lookup_val = params.get(self.lookup_kwarg)
-        self.lookup_val_isnull = get_last_value_from_parameters(
-            params, self.lookup_kwarg_isnull
-        )
-        super().__init__(field, request, params, model, model_admin, field_path)
-
-    def expected_parameters(self):
-        return [self.lookup_kwarg, self.lookup_kwarg_isnull]
-
-    def get_facet_counts(self, pk_attname, filtered_qs):
-        return {
-            f"{i}__c": models.Count(
-                pk_attname,
-                filter=models.Q(
-                    (self.lookup_kwarg, value)
-                    if value is not None
-                    else (self.lookup_kwarg_isnull, True)
-                ),
-            )
-            for i, (value, _) in enumerate(self.field.flatchoices)
-        }
-
-    def choices(self, changelist):
-        add_facets = changelist.add_facets
-        facet_counts = self.get_facet_queryset(changelist) if add_facets else None
-        yield {
-            "selected": self.lookup_val is None,
-            "query_string": changelist.get_query_string(
-                remove=[self.lookup_kwarg, self.lookup_kwarg_isnull]
-            ),
-            "display": _("All"),
-        }
-        none_title = ""
-        for i, (lookup, title) in enumerate(self.field.flatchoices):
-            if add_facets:
-                count = facet_counts[f"{i}__c"]
-                title = f"{title} ({count})"
-            if lookup is None:
-                none_title = title
-                continue
-            yield {
-                "selected": self.lookup_val is not None
-                and str(lookup) in self.lookup_val,
-                "query_string": changelist.get_query_string(
-                    {self.lookup_kwarg: lookup}, [self.lookup_kwarg_isnull]
-                ),
-                "display": title,
-            }
-        if none_title:
-            yield {
-                "selected": bool(self.lookup_val_isnull),
-                "query_string": changelist.get_query_string(
-                    {self.lookup_kwarg_isnull: "True"}, [self.lookup_kwarg]
-                ),
-                "display": none_title,
-            }
-
-
-FieldListFilter.register(lambda f: bool(f.choices), ChoicesFieldListFilter)
-
-
-class DateFieldListFilter(FieldListFilter):
-    def __init__(self, field, request, params, model, model_admin, field_path):
-        self.field_generic = "%s__" % field_path
-        self.date_params = {
-            k: v[-1] for k, v in params.items() if k.startswith(self.field_generic)
-        }
-
-        now = timezone.now()
-        # When time zone support is enabled, convert "now" to the user's time
-        # zone so Django's definition of "Today" matches what the user expects.
-        if timezone.is_aware(now):
-            now = timezone.localtime(now)
-
-        if isinstance(field, models.DateTimeField):
-            today = now.replace(hour=0, minute=0, second=0, microsecond=0)
-        else:  # field is a models.DateField
-            today = now.date()
-        tomorrow = today + datetime.timedelta(days=1)
-        if today.month == 12:
-            next_month = today.replace(year=today.year + 1, month=1, day=1)
-        else:
-            next_month = today.replace(month=today.month + 1, day=1)
-        next_year = today.replace(year=today.year + 1, month=1, day=1)
-
-        self.lookup_kwarg_since = "%s__gte" % field_path
-        self.lookup_kwarg_until = "%s__lt" % field_path
-        self.links = (
-            (_("Any date"), {}),
-            (
-                _("Today"),
-                {
-                    self.lookup_kwarg_since: today,
-                    self.lookup_kwarg_until: tomorrow,
-                },
-            ),
-            (
-                _("Past 7 days"),
-                {
-                    self.lookup_kwarg_since: today - datetime.timedelta(days=7),
-                    self.lookup_kwarg_until: tomorrow,
-                },
-            ),
-            (
-                _("This month"),
-                {
-                    self.lookup_kwarg_since: today.replace(day=1),
-                    self.lookup_kwarg_until: next_month,
-                },
-            ),
-            (
-                _("This year"),
-                {
-                    self.lookup_kwarg_since: today.replace(month=1, day=1),
-                    self.lookup_kwarg_until: next_year,
-                },
-            ),
-        )
-        if field.null:
-            self.lookup_kwarg_isnull = "%s__isnull" % field_path
-            self.links += (
-                (_("No date"), {self.field_generic + "isnull": True}),
-                (_("Has date"), {self.field_generic + "isnull": False}),
-            )
-        super().__init__(field, request, params, model, model_admin, field_path)
-
-    def expected_parameters(self):
-        params = [self.lookup_kwarg_since, self.lookup_kwarg_until]
-        if self.field.null:
-            params.append(self.lookup_kwarg_isnull)
-        return params
-
-    def get_facet_counts(self, pk_attname, filtered_qs):
-        return {
-            f"{i}__c": models.Count(pk_attname, filter=models.Q(**param_dict))
-            for i, (_, param_dict) in enumerate(self.links)
-        }
-
-    def choices(self, changelist):
-        add_facets = changelist.add_facets
-        facet_counts = self.get_facet_queryset(changelist) if add_facets else None
-        for i, (title, param_dict) in enumerate(self.links):
-            param_dict_str = {key: str(value) for key, value in param_dict.items()}
-            if add_facets:
-                count = facet_counts[f"{i}__c"]
-                title = f"{title} ({count})"
-            yield {
-                "selected": self.date_params == param_dict_str,
-                "query_string": changelist.get_query_string(
-                    param_dict_str, [self.field_generic]
-                ),
-                "display": title,
-            }
-
-
-FieldListFilter.register(lambda f: isinstance(f, models.DateField), DateFieldListFilter)
-
-
-# This should be registered last, because it's a last resort. For example,
-# if a field is eligible to use the BooleanFieldListFilter, that'd be much
-# more appropriate, and the AllValuesFieldListFilter won't get used for it.
-class AllValuesFieldListFilter(FieldListFilter):
-    def __init__(self, field, request, params, model, model_admin, field_path):
-        self.lookup_kwarg = field_path
-        self.lookup_kwarg_isnull = "%s__isnull" % field_path
-        self.lookup_val = params.get(self.lookup_kwarg)
-        self.lookup_val_isnull = get_last_value_from_parameters(
-            params, self.lookup_kwarg_isnull
-        )
-        self.empty_value_display = model_admin.get_empty_value_display()
-        parent_model, reverse_path = reverse_field_path(model, field_path)
-        # Obey parent ModelAdmin queryset when deciding which options to show
-        if model == parent_model:
-            queryset = model_admin.get_queryset(request)
-        else:
-            queryset = parent_model._default_manager.all()
-        self.lookup_choices = (
-            queryset.distinct().order_by(field.name).values_list(field.name, flat=True)
-        )
-        super().__init__(field, request, params, model, model_admin, field_path)
-
-    def expected_parameters(self):
-        return [self.lookup_kwarg, self.lookup_kwarg_isnull]
-
-    def get_facet_counts(self, pk_attname, filtered_qs):
-        return {
-            f"{i}__c": models.Count(
-                pk_attname,
-                filter=models.Q(
-                    (self.lookup_kwarg, value)
-                    if value is not None
-                    else (self.lookup_kwarg_isnull, True)
-                ),
-            )
-            for i, value in enumerate(self.lookup_choices)
-        }
-
-    def choices(self, changelist):
-        add_facets = changelist.add_facets
-        facet_counts = self.get_facet_queryset(changelist) if add_facets else None
-        yield {
-            "selected": self.lookup_val is None and self.lookup_val_isnull is None,
-            "query_string": changelist.get_query_string(
-                remove=[self.lookup_kwarg, self.lookup_kwarg_isnull]
-            ),
-            "display": _("All"),
-        }
-        include_none = False
-        count = None
-        empty_title = self.empty_value_display
-        for i, val in enumerate(self.lookup_choices):
-            if add_facets:
-                count = facet_counts[f"{i}__c"]
-            if val is None:
-                include_none = True
-                empty_title = f"{empty_title} ({count})" if add_facets else empty_title
-                continue
-            val = str(val)
-            yield {
-                "selected": self.lookup_val is not None and val in self.lookup_val,
-                "query_string": changelist.get_query_string(
-                    {self.lookup_kwarg: val}, [self.lookup_kwarg_isnull]
-                ),
-                "display": f"{val} ({count})" if add_facets else val,
-            }
-        if include_none:
-            yield {
-                "selected": bool(self.lookup_val_isnull),
-                "query_string": changelist.get_query_string(
-                    {self.lookup_kwarg_isnull: "True"}, [self.lookup_kwarg]
-                ),
-                "display": empty_title,
-            }
-
-
-FieldListFilter.register(lambda f: True, AllValuesFieldListFilter)
-
-
-class RelatedOnlyFieldListFilter(RelatedFieldListFilter):
-    def field_choices(self, field, request, model_admin):
-        pk_qs = (
-            model_admin.get_queryset(request)
-            .distinct()
-            .values_list("%s__pk" % self.field_path, flat=True)
-        )
-        ordering = self.field_admin_ordering(field, request, model_admin)
-        return field.get_choices(
-            include_blank=False, limit_choices_to={"pk__in": pk_qs}, ordering=ordering
-        )
-
-
-class EmptyFieldListFilter(FieldListFilter):
-    def __init__(self, field, request, params, model, model_admin, field_path):
-        if not field.empty_strings_allowed and not field.null:
-            raise ImproperlyConfigured(
-                "The list filter '%s' cannot be used with field '%s' which "
-                "doesn't allow empty strings and nulls."
-                % (
-                    self.__class__.__name__,
-                    field.name,
-                )
-            )
-        self.lookup_kwarg = "%s__isempty" % field_path
-        self.lookup_val = get_last_value_from_parameters(params, self.lookup_kwarg)
-        super().__init__(field, request, params, model, model_admin, field_path)
-
-    def get_lookup_condition(self):
-        lookup_conditions = []
-        if self.field.empty_strings_allowed:
-            lookup_conditions.append((self.field_path, ""))
-        if self.field.null:
-            lookup_conditions.append((f"{self.field_path}__isnull", True))
-        return models.Q.create(lookup_conditions, connector=models.Q.OR)
-
-    def queryset(self, request, queryset):
-        if self.lookup_kwarg not in self.used_parameters:
-            return queryset
-        if self.lookup_val not in ("0", "1"):
-            raise IncorrectLookupParameters
-
-        lookup_condition = self.get_lookup_condition()
-        if self.lookup_val == "1":
-            return queryset.filter(lookup_condition)
-        return queryset.exclude(lookup_condition)
-
-    def expected_parameters(self):
-        return [self.lookup_kwarg]
-
-    def get_facet_counts(self, pk_attname, filtered_qs):
-        lookup_condition = self.get_lookup_condition()
-        return {
-            "empty__c": models.Count(pk_attname, filter=lookup_condition),
-            "not_empty__c": models.Count(pk_attname, filter=~lookup_condition),
-        }
-
-    def choices(self, changelist):
-        add_facets = changelist.add_facets
-        facet_counts = self.get_facet_queryset(changelist) if add_facets else None
-        for lookup, title, count_field in (
-            (None, _("All"), None),
-            ("1", _("Empty"), "empty__c"),
-            ("0", _("Not empty"), "not_empty__c"),
-        ):
-            if add_facets:
-                if count_field is not None:
-                    count = facet_counts[count_field]
-                    title = f"{title} ({count})"
-            yield {
-                "selected": self.lookup_val == lookup,
-                "query_string": changelist.get_query_string(
-                    {self.lookup_kwarg: lookup}
-                ),
-                "display": title,
-            }

+ 0 - 31
static/admin/forms.py

@@ -1,31 +0,0 @@
-from django.contrib.auth.forms import AuthenticationForm, PasswordChangeForm
-from django.core.exceptions import ValidationError
-from django.utils.translation import gettext_lazy as _
-
-
-class AdminAuthenticationForm(AuthenticationForm):
-    """
-    A custom authentication form used in the admin app.
-    """
-
-    error_messages = {
-        **AuthenticationForm.error_messages,
-        "invalid_login": _(
-            "Please enter the correct %(username)s and password for a staff "
-            "account. Note that both fields may be case-sensitive."
-        ),
-    }
-    required_css_class = "required"
-
-    def confirm_login_allowed(self, user):
-        super().confirm_login_allowed(user)
-        if not user.is_staff:
-            raise ValidationError(
-                self.error_messages["invalid_login"],
-                code="invalid_login",
-                params={"username": self.username_field.verbose_name},
-            )
-
-
-class AdminPasswordChangeForm(PasswordChangeForm):
-    required_css_class = "required"

+ 0 - 568
static/admin/helpers.py

@@ -1,568 +0,0 @@
-import json
-
-from django import forms
-from django.contrib.admin.utils import (
-    display_for_field,
-    flatten_fieldsets,
-    help_text_for_field,
-    label_for_field,
-    lookup_field,
-    quote,
-)
-from django.core.exceptions import ObjectDoesNotExist
-from django.db.models.fields.related import (
-    ForeignObjectRel,
-    ManyToManyRel,
-    OneToOneField,
-)
-from django.forms.utils import flatatt
-from django.template.defaultfilters import capfirst, linebreaksbr
-from django.urls import NoReverseMatch, reverse
-from django.utils.functional import cached_property
-from django.utils.html import conditional_escape, format_html
-from django.utils.safestring import mark_safe
-from django.utils.translation import gettext
-from django.utils.translation import gettext_lazy as _
-
-ACTION_CHECKBOX_NAME = "_selected_action"
-
-
-class ActionForm(forms.Form):
-    action = forms.ChoiceField(label=_("Action:"))
-    select_across = forms.BooleanField(
-        label="",
-        required=False,
-        initial=0,
-        widget=forms.HiddenInput({"class": "select-across"}),
-    )
-
-
-class AdminForm:
-    def __init__(
-        self,
-        form,
-        fieldsets,
-        prepopulated_fields,
-        readonly_fields=None,
-        model_admin=None,
-    ):
-        self.form, self.fieldsets = form, fieldsets
-        self.prepopulated_fields = [
-            {"field": form[field_name], "dependencies": [form[f] for f in dependencies]}
-            for field_name, dependencies in prepopulated_fields.items()
-        ]
-        self.model_admin = model_admin
-        if readonly_fields is None:
-            readonly_fields = ()
-        self.readonly_fields = readonly_fields
-
-    def __repr__(self):
-        return (
-            f"<{self.__class__.__qualname__}: "
-            f"form={self.form.__class__.__qualname__} "
-            f"fieldsets={self.fieldsets!r}>"
-        )
-
-    def __iter__(self):
-        for name, options in self.fieldsets:
-            yield Fieldset(
-                self.form,
-                name,
-                readonly_fields=self.readonly_fields,
-                model_admin=self.model_admin,
-                **options,
-            )
-
-    @property
-    def errors(self):
-        return self.form.errors
-
-    @property
-    def non_field_errors(self):
-        return self.form.non_field_errors
-
-    @property
-    def fields(self):
-        return self.form.fields
-
-    @property
-    def is_bound(self):
-        return self.form.is_bound
-
-    @property
-    def media(self):
-        media = self.form.media
-        for fs in self:
-            media += fs.media
-        return media
-
-
-class Fieldset:
-    def __init__(
-        self,
-        form,
-        name=None,
-        readonly_fields=(),
-        fields=(),
-        classes=(),
-        description=None,
-        model_admin=None,
-    ):
-        self.form = form
-        self.name, self.fields = name, fields
-        self.classes = " ".join(classes)
-        self.description = description
-        self.model_admin = model_admin
-        self.readonly_fields = readonly_fields
-
-    @property
-    def media(self):
-        return forms.Media()
-
-    @cached_property
-    def is_collapsible(self):
-        if any([field in self.fields for field in self.form.errors]):
-            return False
-        return "collapse" in self.classes
-
-    def __iter__(self):
-        for field in self.fields:
-            yield Fieldline(
-                self.form, field, self.readonly_fields, model_admin=self.model_admin
-            )
-
-
-class Fieldline:
-    def __init__(self, form, field, readonly_fields=None, model_admin=None):
-        self.form = form  # A django.forms.Form instance
-        if not hasattr(field, "__iter__") or isinstance(field, str):
-            self.fields = [field]
-        else:
-            self.fields = field
-        self.has_visible_field = not all(
-            field in self.form.fields and self.form.fields[field].widget.is_hidden
-            for field in self.fields
-        )
-        self.model_admin = model_admin
-        if readonly_fields is None:
-            readonly_fields = ()
-        self.readonly_fields = readonly_fields
-
-    def __iter__(self):
-        for i, field in enumerate(self.fields):
-            if field in self.readonly_fields:
-                yield AdminReadonlyField(
-                    self.form, field, is_first=(i == 0), model_admin=self.model_admin
-                )
-            else:
-                yield AdminField(self.form, field, is_first=(i == 0))
-
-    def errors(self):
-        return mark_safe(
-            "\n".join(
-                self.form[f].errors.as_ul()
-                for f in self.fields
-                if f not in self.readonly_fields
-            ).strip("\n")
-        )
-
-
-class AdminField:
-    def __init__(self, form, field, is_first):
-        self.field = form[field]  # A django.forms.BoundField instance
-        self.is_first = is_first  # Whether this field is first on the line
-        self.is_checkbox = isinstance(self.field.field.widget, forms.CheckboxInput)
-        self.is_readonly = False
-
-    def label_tag(self):
-        classes = []
-        contents = conditional_escape(self.field.label)
-        if self.is_checkbox:
-            classes.append("vCheckboxLabel")
-
-        if self.field.field.required:
-            classes.append("required")
-        if not self.is_first:
-            classes.append("inline")
-        attrs = {"class": " ".join(classes)} if classes else {}
-        # checkboxes should not have a label suffix as the checkbox appears
-        # to the left of the label.
-        return self.field.label_tag(
-            contents=mark_safe(contents),
-            attrs=attrs,
-            label_suffix="" if self.is_checkbox else None,
-        )
-
-    def errors(self):
-        return mark_safe(self.field.errors.as_ul())
-
-
-class AdminReadonlyField:
-    def __init__(self, form, field, is_first, model_admin=None):
-        # Make self.field look a little bit like a field. This means that
-        # {{ field.name }} must be a useful class name to identify the field.
-        # For convenience, store other field-related data here too.
-        if callable(field):
-            class_name = field.__name__ if field.__name__ != "<lambda>" else ""
-        else:
-            class_name = field
-
-        if form._meta.labels and class_name in form._meta.labels:
-            label = form._meta.labels[class_name]
-        else:
-            label = label_for_field(field, form._meta.model, model_admin, form=form)
-
-        if form._meta.help_texts and class_name in form._meta.help_texts:
-            help_text = form._meta.help_texts[class_name]
-        else:
-            help_text = help_text_for_field(class_name, form._meta.model)
-
-        if field in form.fields:
-            is_hidden = form.fields[field].widget.is_hidden
-        else:
-            is_hidden = False
-
-        self.field = {
-            "name": class_name,
-            "label": label,
-            "help_text": help_text,
-            "field": field,
-            "is_hidden": is_hidden,
-        }
-        self.form = form
-        self.model_admin = model_admin
-        self.is_first = is_first
-        self.is_checkbox = False
-        self.is_readonly = True
-        self.empty_value_display = model_admin.get_empty_value_display()
-
-    def label_tag(self):
-        attrs = {}
-        if not self.is_first:
-            attrs["class"] = "inline"
-        label = self.field["label"]
-        return format_html(
-            "<label{}>{}{}</label>",
-            flatatt(attrs),
-            capfirst(label),
-            self.form.label_suffix,
-        )
-
-    def get_admin_url(self, remote_field, remote_obj):
-        url_name = "admin:%s_%s_change" % (
-            remote_field.model._meta.app_label,
-            remote_field.model._meta.model_name,
-        )
-        try:
-            url = reverse(
-                url_name,
-                args=[quote(remote_obj.pk)],
-                current_app=self.model_admin.admin_site.name,
-            )
-            return format_html('<a href="{}">{}</a>', url, remote_obj)
-        except NoReverseMatch:
-            return str(remote_obj)
-
-    def contents(self):
-        from django.contrib.admin.templatetags.admin_list import _boolean_icon
-
-        field, obj, model_admin = (
-            self.field["field"],
-            self.form.instance,
-            self.model_admin,
-        )
-        try:
-            f, attr, value = lookup_field(field, obj, model_admin)
-        except (AttributeError, ValueError, ObjectDoesNotExist):
-            result_repr = self.empty_value_display
-        else:
-            if field in self.form.fields:
-                widget = self.form[field].field.widget
-                # This isn't elegant but suffices for contrib.auth's
-                # ReadOnlyPasswordHashWidget.
-                if getattr(widget, "read_only", False):
-                    return widget.render(field, value)
-            if f is None:
-                if getattr(attr, "boolean", False):
-                    result_repr = _boolean_icon(value)
-                else:
-                    if hasattr(value, "__html__"):
-                        result_repr = value
-                    else:
-                        result_repr = linebreaksbr(value)
-            else:
-                if isinstance(f.remote_field, ManyToManyRel) and value is not None:
-                    result_repr = ", ".join(map(str, value.all()))
-                elif (
-                    isinstance(f.remote_field, (ForeignObjectRel, OneToOneField))
-                    and value is not None
-                ):
-                    result_repr = self.get_admin_url(f.remote_field, value)
-                else:
-                    result_repr = display_for_field(value, f, self.empty_value_display)
-                result_repr = linebreaksbr(result_repr)
-        return conditional_escape(result_repr)
-
-
-class InlineAdminFormSet:
-    """
-    A wrapper around an inline formset for use in the admin system.
-    """
-
-    def __init__(
-        self,
-        inline,
-        formset,
-        fieldsets,
-        prepopulated_fields=None,
-        readonly_fields=None,
-        model_admin=None,
-        has_add_permission=True,
-        has_change_permission=True,
-        has_delete_permission=True,
-        has_view_permission=True,
-    ):
-        self.opts = inline
-        self.formset = formset
-        self.fieldsets = fieldsets
-        self.model_admin = model_admin
-        if readonly_fields is None:
-            readonly_fields = ()
-        self.readonly_fields = readonly_fields
-        if prepopulated_fields is None:
-            prepopulated_fields = {}
-        self.prepopulated_fields = prepopulated_fields
-        self.classes = " ".join(inline.classes) if inline.classes else ""
-        self.has_add_permission = has_add_permission
-        self.has_change_permission = has_change_permission
-        self.has_delete_permission = has_delete_permission
-        self.has_view_permission = has_view_permission
-
-    def __iter__(self):
-        if self.has_change_permission:
-            readonly_fields_for_editing = self.readonly_fields
-        else:
-            readonly_fields_for_editing = self.readonly_fields + flatten_fieldsets(
-                self.fieldsets
-            )
-
-        for form, original in zip(
-            self.formset.initial_forms, self.formset.get_queryset()
-        ):
-            view_on_site_url = self.opts.get_view_on_site_url(original)
-            yield InlineAdminForm(
-                self.formset,
-                form,
-                self.fieldsets,
-                self.prepopulated_fields,
-                original,
-                readonly_fields_for_editing,
-                model_admin=self.opts,
-                view_on_site_url=view_on_site_url,
-            )
-        for form in self.formset.extra_forms:
-            yield InlineAdminForm(
-                self.formset,
-                form,
-                self.fieldsets,
-                self.prepopulated_fields,
-                None,
-                self.readonly_fields,
-                model_admin=self.opts,
-            )
-        if self.has_add_permission:
-            yield InlineAdminForm(
-                self.formset,
-                self.formset.empty_form,
-                self.fieldsets,
-                self.prepopulated_fields,
-                None,
-                self.readonly_fields,
-                model_admin=self.opts,
-            )
-
-    def fields(self):
-        fk = getattr(self.formset, "fk", None)
-        empty_form = self.formset.empty_form
-        meta_labels = empty_form._meta.labels or {}
-        meta_help_texts = empty_form._meta.help_texts or {}
-        for i, field_name in enumerate(flatten_fieldsets(self.fieldsets)):
-            if fk and fk.name == field_name:
-                continue
-            if not self.has_change_permission or field_name in self.readonly_fields:
-                form_field = empty_form.fields.get(field_name)
-                widget_is_hidden = False
-                if form_field is not None:
-                    widget_is_hidden = form_field.widget.is_hidden
-                yield {
-                    "name": field_name,
-                    "label": meta_labels.get(field_name)
-                    or label_for_field(
-                        field_name,
-                        self.opts.model,
-                        self.opts,
-                        form=empty_form,
-                    ),
-                    "widget": {"is_hidden": widget_is_hidden},
-                    "required": False,
-                    "help_text": meta_help_texts.get(field_name)
-                    or help_text_for_field(field_name, self.opts.model),
-                }
-            else:
-                form_field = empty_form.fields[field_name]
-                label = form_field.label
-                if label is None:
-                    label = label_for_field(
-                        field_name, self.opts.model, self.opts, form=empty_form
-                    )
-                yield {
-                    "name": field_name,
-                    "label": label,
-                    "widget": form_field.widget,
-                    "required": form_field.required,
-                    "help_text": form_field.help_text,
-                }
-
-    def inline_formset_data(self):
-        verbose_name = self.opts.verbose_name
-        return json.dumps(
-            {
-                "name": "#%s" % self.formset.prefix,
-                "options": {
-                    "prefix": self.formset.prefix,
-                    "addText": gettext("Add another %(verbose_name)s")
-                    % {
-                        "verbose_name": capfirst(verbose_name),
-                    },
-                    "deleteText": gettext("Remove"),
-                },
-            }
-        )
-
-    @property
-    def forms(self):
-        return self.formset.forms
-
-    @cached_property
-    def is_collapsible(self):
-        if any(self.formset.errors):
-            return False
-        return "collapse" in self.classes
-
-    def non_form_errors(self):
-        return self.formset.non_form_errors()
-
-    @property
-    def is_bound(self):
-        return self.formset.is_bound
-
-    @property
-    def total_form_count(self):
-        return self.formset.total_form_count
-
-    @property
-    def media(self):
-        media = self.opts.media + self.formset.media
-        for fs in self:
-            media += fs.media
-        return media
-
-
-class InlineAdminForm(AdminForm):
-    """
-    A wrapper around an inline form for use in the admin system.
-    """
-
-    def __init__(
-        self,
-        formset,
-        form,
-        fieldsets,
-        prepopulated_fields,
-        original,
-        readonly_fields=None,
-        model_admin=None,
-        view_on_site_url=None,
-    ):
-        self.formset = formset
-        self.model_admin = model_admin
-        self.original = original
-        self.show_url = original and view_on_site_url is not None
-        self.absolute_url = view_on_site_url
-        super().__init__(
-            form, fieldsets, prepopulated_fields, readonly_fields, model_admin
-        )
-
-    def __iter__(self):
-        for name, options in self.fieldsets:
-            yield InlineFieldset(
-                self.formset,
-                self.form,
-                name,
-                self.readonly_fields,
-                model_admin=self.model_admin,
-                **options,
-            )
-
-    def needs_explicit_pk_field(self):
-        return (
-            # Auto fields are editable, so check for auto or non-editable pk.
-            self.form._meta.model._meta.auto_field
-            or not self.form._meta.model._meta.pk.editable
-            # The pk can be editable, but excluded from the inline.
-            or (
-                self.form._meta.exclude
-                and self.form._meta.model._meta.pk.name in self.form._meta.exclude
-            )
-            or
-            # Also search any parents for an auto field. (The pk info is
-            # propagated to child models so that does not need to be checked
-            # in parents.)
-            any(
-                parent._meta.auto_field or not parent._meta.model._meta.pk.editable
-                for parent in self.form._meta.model._meta.all_parents
-            )
-        )
-
-    def pk_field(self):
-        return AdminField(self.form, self.formset._pk_field.name, False)
-
-    def fk_field(self):
-        fk = getattr(self.formset, "fk", None)
-        if fk:
-            return AdminField(self.form, fk.name, False)
-        else:
-            return ""
-
-    def deletion_field(self):
-        from django.forms.formsets import DELETION_FIELD_NAME
-
-        return AdminField(self.form, DELETION_FIELD_NAME, False)
-
-
-class InlineFieldset(Fieldset):
-    def __init__(self, formset, *args, **kwargs):
-        self.formset = formset
-        super().__init__(*args, **kwargs)
-
-    def __iter__(self):
-        fk = getattr(self.formset, "fk", None)
-        for field in self.fields:
-            if not fk or fk.name != field:
-                yield Fieldline(
-                    self.form, field, self.readonly_fields, model_admin=self.model_admin
-                )
-
-
-class AdminErrorList(forms.utils.ErrorList):
-    """Store errors for the form/formsets in an add/change view."""
-
-    def __init__(self, form, inline_formsets):
-        super().__init__()
-
-        if form.is_bound:
-            self.extend(form.errors.values())
-            for inline_formset in inline_formsets:
-                self.extend(inline_formset.non_form_errors())
-                for errors_in_inline_form in inline_formset.errors:
-                    self.extend(errors_in_inline_form.values())

+ 0 - 0
static/admin/static/admin/img/LICENSE → static/admin/img/LICENSE


+ 0 - 0
static/admin/static/admin/img/README.txt → static/admin/img/README.txt


+ 0 - 0
static/admin/static/admin/img/calendar-icons.svg → static/admin/img/calendar-icons.svg


+ 0 - 0
static/admin/static/admin/img/gis/move_vertex_off.svg → static/admin/img/gis/move_vertex_off.svg


+ 0 - 0
static/admin/static/admin/img/gis/move_vertex_on.svg → static/admin/img/gis/move_vertex_on.svg


+ 0 - 0
static/admin/static/admin/img/icon-addlink.svg → static/admin/img/icon-addlink.svg


+ 0 - 0
static/admin/static/admin/img/icon-alert.svg → static/admin/img/icon-alert.svg


+ 0 - 0
static/admin/static/admin/img/icon-calendar.svg → static/admin/img/icon-calendar.svg


+ 0 - 0
static/admin/static/admin/img/icon-changelink.svg → static/admin/img/icon-changelink.svg


+ 0 - 0
static/admin/static/admin/img/icon-clock.svg → static/admin/img/icon-clock.svg


+ 0 - 0
static/admin/static/admin/img/icon-deletelink.svg → static/admin/img/icon-deletelink.svg


+ 0 - 0
static/admin/static/admin/img/icon-hidelink.svg → static/admin/img/icon-hidelink.svg


+ 0 - 0
static/admin/static/admin/img/icon-no.svg → static/admin/img/icon-no.svg


+ 0 - 0
static/admin/static/admin/img/icon-unknown-alt.svg → static/admin/img/icon-unknown-alt.svg


+ 0 - 0
static/admin/static/admin/img/icon-unknown.svg → static/admin/img/icon-unknown.svg


+ 0 - 0
static/admin/static/admin/img/icon-viewlink.svg → static/admin/img/icon-viewlink.svg


+ 0 - 0
static/admin/static/admin/img/icon-yes.svg → static/admin/img/icon-yes.svg


+ 0 - 0
static/admin/static/admin/img/inline-delete.svg → static/admin/img/inline-delete.svg


+ 0 - 0
static/admin/static/admin/img/search.svg → static/admin/img/search.svg


+ 0 - 0
static/admin/static/admin/img/selector-icons.svg → static/admin/img/selector-icons.svg


+ 0 - 0
static/admin/static/admin/img/sorting-icons.svg → static/admin/img/sorting-icons.svg


+ 0 - 0
static/admin/static/admin/img/tooltag-add.svg → static/admin/img/tooltag-add.svg


+ 0 - 0
static/admin/static/admin/img/tooltag-arrowright.svg → static/admin/img/tooltag-arrowright.svg


+ 0 - 0
static/admin/static/admin/js/SelectBox.js → static/admin/js/SelectBox.js


+ 0 - 0
static/admin/static/admin/js/SelectFilter2.js → static/admin/js/SelectFilter2.js


+ 0 - 0
static/admin/static/admin/js/actions.js → static/admin/js/actions.js


+ 0 - 0
static/admin/static/admin/js/admin/DateTimeShortcuts.js → static/admin/js/admin/DateTimeShortcuts.js


+ 0 - 0
static/admin/static/admin/js/admin/RelatedObjectLookups.js → static/admin/js/admin/RelatedObjectLookups.js


+ 0 - 0
static/admin/static/admin/js/autocomplete.js → static/admin/js/autocomplete.js


+ 0 - 0
static/admin/static/admin/js/calendar.js → static/admin/js/calendar.js


+ 0 - 0
static/admin/static/admin/js/cancel.js → static/admin/js/cancel.js


+ 0 - 0
static/admin/static/admin/js/change_form.js → static/admin/js/change_form.js


+ 0 - 0
static/admin/static/admin/js/core.js → static/admin/js/core.js


+ 0 - 0
static/admin/static/admin/js/filters.js → static/admin/js/filters.js


+ 0 - 0
static/admin/static/admin/js/inlines.js → static/admin/js/inlines.js


+ 0 - 0
static/admin/static/admin/js/jquery.init.js → static/admin/js/jquery.init.js


+ 0 - 0
static/admin/static/admin/js/nav_sidebar.js → static/admin/js/nav_sidebar.js


+ 0 - 0
static/admin/static/admin/js/popup_response.js → static/admin/js/popup_response.js


+ 0 - 0
static/admin/static/admin/js/prepopulate.js → static/admin/js/prepopulate.js


+ 0 - 0
static/admin/static/admin/js/prepopulate_init.js → static/admin/js/prepopulate_init.js


+ 0 - 0
static/admin/static/admin/js/theme.js → static/admin/js/theme.js


+ 0 - 0
static/admin/static/admin/js/unusable_password_field.js → static/admin/js/unusable_password_field.js


+ 0 - 0
static/admin/static/admin/js/urlify.js → static/admin/js/urlify.js


+ 0 - 0
static/admin/static/admin/js/vendor/jquery/LICENSE.txt → static/admin/js/vendor/jquery/LICENSE.txt


+ 0 - 0
static/admin/static/admin/js/vendor/jquery/jquery.js → static/admin/js/vendor/jquery/jquery.js


+ 0 - 0
static/admin/static/admin/js/vendor/jquery/jquery.min.js → static/admin/js/vendor/jquery/jquery.min.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/LICENSE.md → static/admin/js/vendor/select2/LICENSE.md


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/af.js → static/admin/js/vendor/select2/i18n/af.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/ar.js → static/admin/js/vendor/select2/i18n/ar.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/az.js → static/admin/js/vendor/select2/i18n/az.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/bg.js → static/admin/js/vendor/select2/i18n/bg.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/bn.js → static/admin/js/vendor/select2/i18n/bn.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/bs.js → static/admin/js/vendor/select2/i18n/bs.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/ca.js → static/admin/js/vendor/select2/i18n/ca.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/cs.js → static/admin/js/vendor/select2/i18n/cs.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/da.js → static/admin/js/vendor/select2/i18n/da.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/de.js → static/admin/js/vendor/select2/i18n/de.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/dsb.js → static/admin/js/vendor/select2/i18n/dsb.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/el.js → static/admin/js/vendor/select2/i18n/el.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/en.js → static/admin/js/vendor/select2/i18n/en.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/es.js → static/admin/js/vendor/select2/i18n/es.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/et.js → static/admin/js/vendor/select2/i18n/et.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/eu.js → static/admin/js/vendor/select2/i18n/eu.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/fa.js → static/admin/js/vendor/select2/i18n/fa.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/fi.js → static/admin/js/vendor/select2/i18n/fi.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/fr.js → static/admin/js/vendor/select2/i18n/fr.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/gl.js → static/admin/js/vendor/select2/i18n/gl.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/he.js → static/admin/js/vendor/select2/i18n/he.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/hi.js → static/admin/js/vendor/select2/i18n/hi.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/hr.js → static/admin/js/vendor/select2/i18n/hr.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/hsb.js → static/admin/js/vendor/select2/i18n/hsb.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/hu.js → static/admin/js/vendor/select2/i18n/hu.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/hy.js → static/admin/js/vendor/select2/i18n/hy.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/id.js → static/admin/js/vendor/select2/i18n/id.js


+ 0 - 0
static/admin/static/admin/js/vendor/select2/i18n/is.js → static/admin/js/vendor/select2/i18n/is.js


Неке датотеке нису приказане због велике количине промена