测试gitnore

This commit is contained in:
ladeng07
2022-05-06 15:45:57 +08:00
parent 12f390949b
commit 51552904f9
2347 changed files with 120102 additions and 53549 deletions
@@ -6,47 +6,31 @@ from django.views.generic.list import BaseListView
class AutocompleteJsonView(BaseListView):
"""Handle AutocompleteWidget's AJAX requests for data."""
paginate_by = 20
admin_site = None
def get(self, request, *args, **kwargs):
"""
Return a JsonResponse with search results as defined in
serialize_result(), by default:
Return a JsonResponse with search results of the form:
{
results: [{id: "123" text: "foo"}],
pagination: {more: true}
}
"""
(
self.term,
self.model_admin,
self.source_field,
to_field_name,
) = self.process_request(request)
self.term, self.model_admin, self.source_field, to_field_name = self.process_request(request)
if not self.has_perm(request):
raise PermissionDenied
self.object_list = self.get_queryset()
context = self.get_context_data()
return JsonResponse(
{
"results": [
self.serialize_result(obj, to_field_name)
for obj in context["object_list"]
],
"pagination": {"more": context["page_obj"].has_next()},
}
)
def serialize_result(self, obj, to_field_name):
"""
Convert the provided model object to a dictionary that is added to the
results list.
"""
return {"id": str(getattr(obj, to_field_name)), "text": str(obj)}
return JsonResponse({
'results': [
{'id': str(getattr(obj, to_field_name)), 'text': str(obj)}
for obj in context['object_list']
],
'pagination': {'more': context['page_obj'].has_next()},
})
def get_paginator(self, *args, **kwargs):
"""Use the ModelAdmin's paginator."""
@@ -56,9 +40,7 @@ class AutocompleteJsonView(BaseListView):
"""Return queryset based on ModelAdmin.get_search_results()."""
qs = self.model_admin.get_queryset(self.request)
qs = qs.complex_filter(self.source_field.get_limit_choices_to())
qs, search_use_distinct = self.model_admin.get_search_results(
self.request, qs, self.term
)
qs, search_use_distinct = self.model_admin.get_search_results(self.request, qs, self.term)
if search_use_distinct:
qs = qs.distinct()
return qs
@@ -74,11 +56,11 @@ class AutocompleteJsonView(BaseListView):
Raise Http404 if the target model admin is not configured properly with
search_fields.
"""
term = request.GET.get("term", "")
term = request.GET.get('term', '')
try:
app_label = request.GET["app_label"]
model_name = request.GET["model_name"]
field_name = request.GET["field_name"]
app_label = request.GET['app_label']
model_name = request.GET['model_name']
field_name = request.GET['field_name']
except KeyError as e:
raise PermissionDenied from e
@@ -104,13 +86,11 @@ class AutocompleteJsonView(BaseListView):
# Validate suitability of objects.
if not model_admin.get_search_fields(request):
raise Http404(
"%s must have search_fields for the autocomplete_view."
% type(model_admin).__qualname__
'%s must have search_fields for the autocomplete_view.' %
type(model_admin).__qualname__
)
to_field_name = getattr(
source_field.remote_field, "field_name", remote_model._meta.pk.attname
)
to_field_name = getattr(source_field.remote_field, 'field_name', remote_model._meta.pk.attname)
to_field_name = remote_model._meta.get_field(to_field_name).attname
if not model_admin.to_field_allowed(request, to_field_name):
raise PermissionDenied
@@ -2,9 +2,8 @@ from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.auth.decorators import user_passes_test
def staff_member_required(
view_func=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url="admin:login"
):
def staff_member_required(view_func=None, redirect_field_name=REDIRECT_FIELD_NAME,
login_url='admin:login'):
"""
Decorator for views that checks that the user is logged in and is a staff
member, redirecting to the login page if necessary.
@@ -12,7 +11,7 @@ def staff_member_required(
actual_decorator = user_passes_test(
lambda u: u.is_active and u.is_staff,
login_url=login_url,
redirect_field_name=redirect_field_name,
redirect_field_name=redirect_field_name
)
if view_func:
return actual_decorator(view_func)
@@ -5,24 +5,16 @@ from django.conf import settings
from django.contrib import messages
from django.contrib.admin import FieldListFilter
from django.contrib.admin.exceptions import (
DisallowedModelAdminLookup,
DisallowedModelAdminToField,
DisallowedModelAdminLookup, DisallowedModelAdminToField,
)
from django.contrib.admin.options import (
IS_POPUP_VAR,
TO_FIELD_VAR,
IncorrectLookupParameters,
IS_POPUP_VAR, TO_FIELD_VAR, IncorrectLookupParameters,
)
from django.contrib.admin.utils import (
get_fields_from_path,
lookup_spawns_duplicates,
prepare_lookup_value,
quote,
get_fields_from_path, lookup_needs_distinct, prepare_lookup_value, quote,
)
from django.core.exceptions import (
FieldDoesNotExist,
ImproperlyConfigured,
SuspiciousOperation,
FieldDoesNotExist, ImproperlyConfigured, SuspiciousOperation,
)
from django.core.paginator import InvalidPage
from django.db.models import Exists, F, Field, ManyToOneRel, OrderBy, OuterRef
@@ -33,13 +25,15 @@ from django.utils.timezone import make_aware
from django.utils.translation import gettext
# Changelist settings
ALL_VAR = "all"
ORDER_VAR = "o"
PAGE_VAR = "p"
SEARCH_VAR = "q"
ERROR_FLAG = "e"
ALL_VAR = 'all'
ORDER_VAR = 'o'
ORDER_TYPE_VAR = 'ot'
PAGE_VAR = 'p'
SEARCH_VAR = 'q'
ERROR_FLAG = 'e'
IGNORED_PARAMS = (ALL_VAR, ORDER_VAR, SEARCH_VAR, IS_POPUP_VAR, TO_FIELD_VAR)
IGNORED_PARAMS = (
ALL_VAR, ORDER_VAR, ORDER_TYPE_VAR, SEARCH_VAR, IS_POPUP_VAR, TO_FIELD_VAR)
class ChangeListSearchForm(forms.Form):
@@ -54,23 +48,9 @@ class ChangeListSearchForm(forms.Form):
class ChangeList:
search_form_class = ChangeListSearchForm
def __init__(
self,
request,
model,
list_display,
list_display_links,
list_filter,
date_hierarchy,
search_fields,
list_select_related,
list_per_page,
list_max_show_all,
list_editable,
model_admin,
sortable_by,
search_help_text,
):
def __init__(self, request, model, list_display, list_display_links,
list_filter, date_hierarchy, search_fields, list_select_related,
list_per_page, list_max_show_all, list_editable, model_admin, sortable_by):
self.model = model
self.opts = model._meta
self.lookup_opts = self.opts
@@ -89,14 +69,13 @@ class ChangeList:
self.model_admin = model_admin
self.preserved_filters = model_admin.get_preserved_filters(request)
self.sortable_by = sortable_by
self.search_help_text = search_help_text
# Get search parameters from the query string.
_search_form = self.search_form_class(request.GET)
if not _search_form.is_valid():
for error in _search_form.errors.values():
messages.error(request, ", ".join(error))
self.query = _search_form.cleaned_data.get(SEARCH_VAR) or ""
messages.error(request, ', '.join(error))
self.query = _search_form.cleaned_data.get(SEARCH_VAR) or ''
try:
self.page_num = int(request.GET.get(PAGE_VAR, 1))
except ValueError:
@@ -105,9 +84,7 @@ class ChangeList:
self.is_popup = IS_POPUP_VAR in request.GET
to_field = request.GET.get(TO_FIELD_VAR)
if to_field and not model_admin.to_field_allowed(request, to_field):
raise DisallowedModelAdminToField(
"The field %s cannot be referenced." % to_field
)
raise DisallowedModelAdminToField("The field %s cannot be referenced." % to_field)
self.to_field = to_field
self.params = dict(request.GET.items())
if PAGE_VAR in self.params:
@@ -122,21 +99,14 @@ class ChangeList:
self.queryset = self.get_queryset(request)
self.get_results(request)
if self.is_popup:
title = gettext("Select %s")
title = gettext('Select %s')
elif self.model_admin.has_change_permission(request):
title = gettext("Select %s to change")
title = gettext('Select %s to change')
else:
title = gettext("Select %s to view")
title = gettext('Select %s to view')
self.title = title % self.opts.verbose_name
self.pk_attname = self.lookup_opts.pk.attname
def __repr__(self):
return "<%s: model=%s model_admin=%s>" % (
self.__class__.__qualname__,
self.model.__qualname__,
self.model_admin.__class__.__qualname__,
)
def get_filters_params(self, params=None):
"""
Return all params except IGNORED_PARAMS.
@@ -180,21 +150,14 @@ class ChangeList:
field = get_fields_from_path(self.model, field_path)[-1]
spec = field_list_filter_class(
field,
request,
lookup_params,
self.model,
self.model_admin,
field_path=field_path,
field, request, lookup_params,
self.model, self.model_admin, field_path=field_path,
)
# field_list_filter_class removes any lookup_params it
# processes. If that happened, check if duplicates should be
# removed.
# processes. If that happened, check if distinct() is needed to
# remove duplicate results.
if lookup_params_count > len(lookup_params):
may_have_duplicates |= lookup_spawns_duplicates(
self.lookup_opts,
field_path,
)
may_have_duplicates |= lookup_needs_distinct(self.lookup_opts, field_path)
if spec and spec.has_output():
filter_specs.append(spec)
if lookup_params_count > len(lookup_params):
@@ -203,10 +166,10 @@ class ChangeList:
if self.date_hierarchy:
# Create bounded lookup parameters so that the query is more
# efficient.
year = lookup_params.pop("%s__year" % self.date_hierarchy, None)
year = lookup_params.pop('%s__year' % self.date_hierarchy, None)
if year is not None:
month = lookup_params.pop("%s__month" % self.date_hierarchy, None)
day = lookup_params.pop("%s__day" % self.date_hierarchy, None)
month = lookup_params.pop('%s__month' % self.date_hierarchy, None)
day = lookup_params.pop('%s__day' % self.date_hierarchy, None)
try:
from_date = datetime(
int(year),
@@ -226,28 +189,23 @@ class ChangeList:
if settings.USE_TZ:
from_date = make_aware(from_date)
to_date = make_aware(to_date)
lookup_params.update(
{
"%s__gte" % self.date_hierarchy: from_date,
"%s__lt" % self.date_hierarchy: to_date,
}
)
lookup_params.update({
'%s__gte' % self.date_hierarchy: from_date,
'%s__lt' % self.date_hierarchy: to_date,
})
# At this point, all the parameters used by the various ListFilters
# have been removed from lookup_params, which now only contains other
# parameters passed via the query string. We now loop through the
# remaining parameters both to ensure that all the parameters are valid
# fields and to determine if at least one of them spawns duplicates. If
# fields and to determine if at least one of them needs distinct(). If
# the lookup parameters aren't real fields, then bail out.
try:
for key, value in lookup_params.items():
lookup_params[key] = prepare_lookup_value(key, value)
may_have_duplicates |= lookup_spawns_duplicates(self.lookup_opts, key)
may_have_duplicates |= lookup_needs_distinct(self.lookup_opts, key)
return (
filter_specs,
bool(filter_specs),
lookup_params,
may_have_duplicates,
filter_specs, bool(filter_specs), lookup_params, may_have_duplicates,
has_active_filters,
)
except FieldDoesNotExist as e:
@@ -269,12 +227,10 @@ class ChangeList:
del p[k]
else:
p[k] = v
return "?%s" % urlencode(sorted(p.items()))
return '?%s' % urlencode(sorted(p.items()))
def get_results(self, request):
paginator = self.model_admin.get_paginator(
request, self.queryset, self.list_per_page
)
paginator = self.model_admin.get_paginator(request, self.queryset, self.list_per_page)
# Get the number of objects, with admin filters applied.
result_count = paginator.count
@@ -299,9 +255,7 @@ class ChangeList:
self.show_full_result_count = self.model_admin.show_full_result_count
# Admin actions are shown if there is at least one entry
# or if entries are not counted because show_full_result_count is disabled
self.show_admin_actions = not self.show_full_result_count or bool(
full_result_count
)
self.show_admin_actions = not self.show_full_result_count or bool(full_result_count)
self.full_result_count = full_result_count
self.result_list = result_list
self.can_show_all = can_show_all
@@ -336,9 +290,9 @@ class ChangeList:
attr = getattr(self.model_admin, field_name)
else:
attr = getattr(self.model, field_name)
if isinstance(attr, property) and hasattr(attr, "fget"):
if isinstance(attr, property) and hasattr(attr, 'fget'):
attr = attr.fget
return getattr(attr, "admin_order_field", None)
return getattr(attr, 'admin_order_field', None)
def get_ordering(self, request, queryset):
"""
@@ -350,32 +304,28 @@ class ChangeList:
constructed ordering.
"""
params = self.params
ordering = list(
self.model_admin.get_ordering(request) or self._get_default_ordering()
)
ordering = list(self.model_admin.get_ordering(request) or self._get_default_ordering())
if ORDER_VAR in params:
# Clear ordering and used params
ordering = []
order_params = params[ORDER_VAR].split(".")
order_params = params[ORDER_VAR].split('.')
for p in order_params:
try:
none, pfx, idx = p.rpartition("-")
none, pfx, idx = p.rpartition('-')
field_name = self.list_display[int(idx)]
order_field = self.get_ordering_field(field_name)
if not order_field:
continue # No 'admin_order_field', skip it
if isinstance(order_field, OrderBy):
if pfx == "-":
if pfx == '-':
order_field = order_field.copy()
order_field.reverse_ordering()
ordering.append(order_field)
elif hasattr(order_field, "resolve_expression"):
elif hasattr(order_field, 'resolve_expression'):
# order_field is an expression.
ordering.append(
order_field.desc() if pfx == "-" else order_field.asc()
)
ordering.append(order_field.desc() if pfx == '-' else order_field.asc())
# reverse order if order_field has already "-" as prefix
elif order_field.startswith("-") and pfx == "-":
elif order_field.startswith('-') and pfx == '-':
ordering.append(order_field[1:])
else:
ordering.append(pfx + order_field)
@@ -396,16 +346,15 @@ class ChangeList:
"""
ordering = list(ordering)
ordering_fields = set()
total_ordering_fields = {"pk"} | {
field.attname
for field in self.lookup_opts.fields
total_ordering_fields = {'pk'} | {
field.attname for field in self.lookup_opts.fields
if field.unique and not field.null
}
for part in ordering:
# Search for single field providing a total ordering.
field_name = None
if isinstance(part, str):
field_name = part.lstrip("-")
field_name = part.lstrip('-')
elif isinstance(part, F):
field_name = part.name
elif isinstance(part, OrderBy) and isinstance(part.expression, F):
@@ -437,9 +386,7 @@ class ChangeList:
)
for field_names in constraint_field_names:
# Normalize attname references by using get_field().
fields = [
self.lookup_opts.get_field(field_name) for field_name in field_names
]
fields = [self.lookup_opts.get_field(field_name) for field_name in field_names]
# Composite unique constraints containing a nullable column
# cannot ensure total ordering.
if any(field.null for field in fields):
@@ -449,7 +396,7 @@ class ChangeList:
else:
# If no set of unique fields is present in the ordering, rely
# on the primary key to provide total ordering.
ordering.append("-pk")
ordering.append('-pk')
return ordering
def get_ordering_field_columns(self):
@@ -469,27 +416,27 @@ class ChangeList:
if not isinstance(field, OrderBy):
field = field.asc()
if isinstance(field.expression, F):
order_type = "desc" if field.descending else "asc"
order_type = 'desc' if field.descending else 'asc'
field = field.expression.name
else:
continue
elif field.startswith("-"):
elif field.startswith('-'):
field = field[1:]
order_type = "desc"
order_type = 'desc'
else:
order_type = "asc"
order_type = 'asc'
for index, attr in enumerate(self.list_display):
if self.get_ordering_field(attr) == field:
ordering_fields[index] = order_type
break
else:
for p in self.params[ORDER_VAR].split("."):
none, pfx, idx = p.rpartition("-")
for p in self.params[ORDER_VAR].split('.'):
none, pfx, idx = p.rpartition('-')
try:
idx = int(idx)
except ValueError:
continue # skip it
ordering_fields[idx] = "desc" if pfx == "-" else "asc"
ordering_fields[idx] = 'desc' if pfx == '-' else 'asc'
return ordering_fields
def get_queryset(self, request):
@@ -527,9 +474,7 @@ class ChangeList:
# Apply search results
qs, search_may_have_duplicates = self.model_admin.get_search_results(
request,
qs,
self.query,
request, qs, self.query,
)
# Set query string for clearing all filters.
@@ -539,7 +484,7 @@ class ChangeList:
)
# Remove duplicates from results, if necessary
if filters_may_have_duplicates | search_may_have_duplicates:
qs = qs.filter(pk=OuterRef("pk"))
qs = qs.filter(pk=OuterRef('pk'))
qs = self.root_queryset.filter(Exists(qs))
# Set ordering.
@@ -578,8 +523,7 @@ class ChangeList:
def url_for_result(self, result):
pk = getattr(result, self.pk_attname)
return reverse(
"admin:%s_%s_change" % (self.opts.app_label, self.opts.model_name),
args=(quote(pk),),
current_app=self.model_admin.admin_site.name,
)
return reverse('admin:%s_%s_change' % (self.opts.app_label,
self.opts.model_name),
args=(quote(pk),),
current_app=self.model_admin.admin_site.name)