Test autocomplete dropdown

This commit is contained in:
zandercymatics 2024-02-14 13:22:10 -07:00
parent 63438f0193
commit 6a0587d5fe
No known key found for this signature in database
GPG key ID: FF4636ABEC9682B7
2 changed files with 183 additions and 197 deletions

View file

@ -1,5 +1,6 @@
import logging
import time
from django.db import transaction
from django import forms
from django.db.models.functions import Concat, Coalesce
from django.db.models import Value, CharField
@ -59,8 +60,6 @@ class MultiFieldSortableChangeList(admin.views.main.ChangeList):
Mostly identical to the base implementation, except that now it can return
a list of order_field objects rather than just one.
"""
logger.info("timing get_ordering")
with Timer() as t:
params = self.params
ordering = list(self.model_admin.get_ordering(request) or self._get_default_ordering())
@ -129,18 +128,24 @@ class AdminSortFields:
_name_sort = Concat("first_name", "last_name", "email")
# Define a mapping of field names to model querysets and sort expressions
sort_mapping = {
# == Contact == #
"other_contacts": (Contact, _name_sort),
"authorizing_official": (Contact, _name_sort),
"submitter": (Contact, _name_sort),
"current_websites": (Website, "website"),
"alternative_domains": (Website, "website"),
# == User == #
"creator": (User, _name_sort),
"user": (User, _name_sort),
"investigator": (User, _name_sort),
# == Website == #
"current_websites": (Website, "website"),
"alternative_domains": (Website, "website"),
# == DraftDomain == #
"requested_domain": (DraftDomain, "name"),
# == DomainApplication == #
"domain_application": (DomainApplication, "requested_domain__name"),
# == Domain == #
"domain": (Domain, "name"),
"approved_domain": (Domain, "name"),
"requested_domain": (DraftDomain, "name"),
"domain_application": (DomainApplication, "requested_domain__name"),
}
@classmethod
@ -155,6 +160,9 @@ class AdminSortFields:
case "investigator":
# We should only return users who are staff
return model.objects.filter(is_staff=True).order_by(order_by)
case "submitter":
db_field_model = db_field.model
db_field_model.objects.select_related("submitter")
case _:
# If no case is defined, return the default
return model.objects.order_by(order_by)
@ -208,13 +216,9 @@ class ListHeaderAdmin(AuditedAdmin, OrderableFieldsMixin):
Reference: https://code.djangoproject.com/ticket/31975
"""
logger.info("timing get_changelist")
with Timer() as t:
return MultiFieldSortableChangeList
def changelist_view(self, request, extra_context=None):
logger.info("timing changelist_view")
with Timer() as t:
if extra_context is None:
extra_context = {}
# Get the filtered values
@ -231,8 +235,6 @@ class ListHeaderAdmin(AuditedAdmin, OrderableFieldsMixin):
parameter_value: string}
TODO: convert investigator id to investigator username
"""
logger.info("timing get_filters")
with Timer() as t:
filters = []
# Retrieve the filter parameters
for param in request.GET.keys():
@ -775,9 +777,6 @@ class DomainApplicationAdmin(ListHeaderAdmin):
"""Lookup reimplementation, gets users of is_staff.
Returns a list of tuples consisting of (user.id, user)
"""
logger.info("timing lookups")
with Timer() as t:
# Select all investigators that are staff, then order by name and email
privileged_users = (
DomainApplication.objects.select_related("investigator")
@ -804,18 +803,11 @@ class DomainApplicationAdmin(ListHeaderAdmin):
def queryset(self, request, queryset):
"""Custom queryset implementation, filters by investigator"""
logger.info("timing queryset")
with Timer() as t:
if self.value() is None:
return queryset
else:
return queryset.filter(investigator__id__exact=self.value())
def __new__(self, *args, **kwargs):
logger.info("timing __new__")
with Timer() as t:
return super().__new__(self, *args, **kwargs)
# Columns
list_display = [
"requested_domain",
@ -907,7 +899,7 @@ class DomainApplicationAdmin(ListHeaderAdmin):
"anything_else",
"is_policy_acknowledged",
]
autocomplete_fields = ["submitter"]
filter_horizontal = ("current_websites", "alternative_domains", "other_contacts")
# Table ordering
@ -918,19 +910,15 @@ class DomainApplicationAdmin(ListHeaderAdmin):
def formfield_for_manytomany(self, db_field, request, **kwargs):
logger.info(f"timing formfield_for_manytomany -> {db_field.name}")
with Timer() as t:
if db_field.name in {"current_websites", "alternative_domains"}:
kwargs["queryset"] = models.Website.objects.all().order_by("website") # Sort websites
return super().formfield_for_manytomany(db_field, request, **kwargs)
def formfield_for_foreignkey(self, db_field, request, **kwargs):
logger.info(f"timing formfield_for_foreignkey -> {db_field.name}")
with Timer() as t:
print(f"This is the db_field: {db_field}")
return super().formfield_for_foreignkey(db_field, request, **kwargs)
# Trigger action when a fieldset is changed
def save_model(self, request, obj, form, change):
logger.info("timing save_model")
with Timer() as t:
if obj and obj.creator.status != models.User.RESTRICTED:
if change: # Check if the application is being edited
# Get the original application from the database
@ -996,8 +984,6 @@ class DomainApplicationAdmin(ListHeaderAdmin):
admin user permissions and the application creator's status, so
we'll use the baseline readonly_fields and extend it as needed.
"""
logger.info("timing get_readonly_fields")
with Timer() as t:
readonly_fields = list(self.readonly_fields)
# Check if the creator is restricted
@ -1017,8 +1003,6 @@ class DomainApplicationAdmin(ListHeaderAdmin):
return readonly_fields
def display_restricted_warning(self, request, obj):
logger.info("timing display_restricted_warning")
with Timer() as t:
if obj and obj.creator.status == models.User.RESTRICTED:
messages.warning(
request,
@ -1026,8 +1010,6 @@ class DomainApplicationAdmin(ListHeaderAdmin):
)
def change_view(self, request, object_id, form_url="", extra_context=None):
logger.info("timing change_view")
with Timer() as t:
obj = self.get_object(request, object_id)
self.display_restricted_warning(request, obj)
return super().change_view(request, object_id, form_url, extra_context)

View file

@ -270,3 +270,7 @@ h1, h2, h3,
margin: 0!important;
}
}
.select2-dropdown {
display: inline-grid !important;
}