mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-25 20:18:38 +02:00
Test autocomplete dropdown
This commit is contained in:
parent
63438f0193
commit
6a0587d5fe
2 changed files with 183 additions and 197 deletions
|
@ -1,5 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
|
from django.db import transaction
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.db.models.functions import Concat, Coalesce
|
from django.db.models.functions import Concat, Coalesce
|
||||||
from django.db.models import Value, CharField
|
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
|
Mostly identical to the base implementation, except that now it can return
|
||||||
a list of order_field objects rather than just one.
|
a list of order_field objects rather than just one.
|
||||||
"""
|
"""
|
||||||
logger.info("timing get_ordering")
|
|
||||||
with Timer() as t:
|
|
||||||
params = self.params
|
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())
|
||||||
|
|
||||||
|
@ -129,18 +128,24 @@ class AdminSortFields:
|
||||||
_name_sort = Concat("first_name", "last_name", "email")
|
_name_sort = Concat("first_name", "last_name", "email")
|
||||||
# Define a mapping of field names to model querysets and sort expressions
|
# Define a mapping of field names to model querysets and sort expressions
|
||||||
sort_mapping = {
|
sort_mapping = {
|
||||||
|
# == Contact == #
|
||||||
"other_contacts": (Contact, _name_sort),
|
"other_contacts": (Contact, _name_sort),
|
||||||
"authorizing_official": (Contact, _name_sort),
|
"authorizing_official": (Contact, _name_sort),
|
||||||
"submitter": (Contact, _name_sort),
|
"submitter": (Contact, _name_sort),
|
||||||
"current_websites": (Website, "website"),
|
# == User == #
|
||||||
"alternative_domains": (Website, "website"),
|
|
||||||
"creator": (User, _name_sort),
|
"creator": (User, _name_sort),
|
||||||
"user": (User, _name_sort),
|
"user": (User, _name_sort),
|
||||||
"investigator": (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"),
|
"domain": (Domain, "name"),
|
||||||
"approved_domain": (Domain, "name"),
|
"approved_domain": (Domain, "name"),
|
||||||
"requested_domain": (DraftDomain, "name"),
|
|
||||||
"domain_application": (DomainApplication, "requested_domain__name"),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -155,6 +160,9 @@ class AdminSortFields:
|
||||||
case "investigator":
|
case "investigator":
|
||||||
# We should only return users who are staff
|
# We should only return users who are staff
|
||||||
return model.objects.filter(is_staff=True).order_by(order_by)
|
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 _:
|
case _:
|
||||||
# If no case is defined, return the default
|
# If no case is defined, return the default
|
||||||
return model.objects.order_by(order_by)
|
return model.objects.order_by(order_by)
|
||||||
|
@ -208,13 +216,9 @@ class ListHeaderAdmin(AuditedAdmin, OrderableFieldsMixin):
|
||||||
|
|
||||||
Reference: https://code.djangoproject.com/ticket/31975
|
Reference: https://code.djangoproject.com/ticket/31975
|
||||||
"""
|
"""
|
||||||
logger.info("timing get_changelist")
|
|
||||||
with Timer() as t:
|
|
||||||
return MultiFieldSortableChangeList
|
return MultiFieldSortableChangeList
|
||||||
|
|
||||||
def changelist_view(self, request, extra_context=None):
|
def changelist_view(self, request, extra_context=None):
|
||||||
logger.info("timing changelist_view")
|
|
||||||
with Timer() as t:
|
|
||||||
if extra_context is None:
|
if extra_context is None:
|
||||||
extra_context = {}
|
extra_context = {}
|
||||||
# Get the filtered values
|
# Get the filtered values
|
||||||
|
@ -231,8 +235,6 @@ class ListHeaderAdmin(AuditedAdmin, OrderableFieldsMixin):
|
||||||
parameter_value: string}
|
parameter_value: string}
|
||||||
TODO: convert investigator id to investigator username
|
TODO: convert investigator id to investigator username
|
||||||
"""
|
"""
|
||||||
logger.info("timing get_filters")
|
|
||||||
with Timer() as t:
|
|
||||||
filters = []
|
filters = []
|
||||||
# Retrieve the filter parameters
|
# Retrieve the filter parameters
|
||||||
for param in request.GET.keys():
|
for param in request.GET.keys():
|
||||||
|
@ -775,9 +777,6 @@ class DomainApplicationAdmin(ListHeaderAdmin):
|
||||||
"""Lookup reimplementation, gets users of is_staff.
|
"""Lookup reimplementation, gets users of is_staff.
|
||||||
Returns a list of tuples consisting of (user.id, user)
|
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
|
# Select all investigators that are staff, then order by name and email
|
||||||
privileged_users = (
|
privileged_users = (
|
||||||
DomainApplication.objects.select_related("investigator")
|
DomainApplication.objects.select_related("investigator")
|
||||||
|
@ -804,18 +803,11 @@ class DomainApplicationAdmin(ListHeaderAdmin):
|
||||||
|
|
||||||
def queryset(self, request, queryset):
|
def queryset(self, request, queryset):
|
||||||
"""Custom queryset implementation, filters by investigator"""
|
"""Custom queryset implementation, filters by investigator"""
|
||||||
logger.info("timing queryset")
|
|
||||||
with Timer() as t:
|
|
||||||
if self.value() is None:
|
if self.value() is None:
|
||||||
return queryset
|
return queryset
|
||||||
else:
|
else:
|
||||||
return queryset.filter(investigator__id__exact=self.value())
|
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
|
# Columns
|
||||||
list_display = [
|
list_display = [
|
||||||
"requested_domain",
|
"requested_domain",
|
||||||
|
@ -907,7 +899,7 @@ class DomainApplicationAdmin(ListHeaderAdmin):
|
||||||
"anything_else",
|
"anything_else",
|
||||||
"is_policy_acknowledged",
|
"is_policy_acknowledged",
|
||||||
]
|
]
|
||||||
|
autocomplete_fields = ["submitter"]
|
||||||
filter_horizontal = ("current_websites", "alternative_domains", "other_contacts")
|
filter_horizontal = ("current_websites", "alternative_domains", "other_contacts")
|
||||||
|
|
||||||
# Table ordering
|
# Table ordering
|
||||||
|
@ -918,19 +910,15 @@ class DomainApplicationAdmin(ListHeaderAdmin):
|
||||||
def formfield_for_manytomany(self, db_field, request, **kwargs):
|
def formfield_for_manytomany(self, db_field, request, **kwargs):
|
||||||
logger.info(f"timing formfield_for_manytomany -> {db_field.name}")
|
logger.info(f"timing formfield_for_manytomany -> {db_field.name}")
|
||||||
with Timer() as t:
|
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)
|
return super().formfield_for_manytomany(db_field, request, **kwargs)
|
||||||
|
|
||||||
def formfield_for_foreignkey(self, 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:
|
with Timer() as t:
|
||||||
print(f"This is the db_field: {db_field}")
|
|
||||||
return super().formfield_for_foreignkey(db_field, request, **kwargs)
|
return super().formfield_for_foreignkey(db_field, request, **kwargs)
|
||||||
|
|
||||||
# Trigger action when a fieldset is changed
|
# Trigger action when a fieldset is changed
|
||||||
def save_model(self, request, obj, form, change):
|
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 obj and obj.creator.status != models.User.RESTRICTED:
|
||||||
if change: # Check if the application is being edited
|
if change: # Check if the application is being edited
|
||||||
# Get the original application from the database
|
# Get the original application from the database
|
||||||
|
@ -996,8 +984,6 @@ class DomainApplicationAdmin(ListHeaderAdmin):
|
||||||
admin user permissions and the application creator's status, so
|
admin user permissions and the application creator's status, so
|
||||||
we'll use the baseline readonly_fields and extend it as needed.
|
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)
|
readonly_fields = list(self.readonly_fields)
|
||||||
|
|
||||||
# Check if the creator is restricted
|
# Check if the creator is restricted
|
||||||
|
@ -1017,8 +1003,6 @@ class DomainApplicationAdmin(ListHeaderAdmin):
|
||||||
return readonly_fields
|
return readonly_fields
|
||||||
|
|
||||||
def display_restricted_warning(self, request, obj):
|
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:
|
if obj and obj.creator.status == models.User.RESTRICTED:
|
||||||
messages.warning(
|
messages.warning(
|
||||||
request,
|
request,
|
||||||
|
@ -1026,8 +1010,6 @@ class DomainApplicationAdmin(ListHeaderAdmin):
|
||||||
)
|
)
|
||||||
|
|
||||||
def change_view(self, request, object_id, form_url="", extra_context=None):
|
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)
|
obj = self.get_object(request, object_id)
|
||||||
self.display_restricted_warning(request, obj)
|
self.display_restricted_warning(request, obj)
|
||||||
return super().change_view(request, object_id, form_url, extra_context)
|
return super().change_view(request, object_id, form_url, extra_context)
|
||||||
|
|
|
@ -270,3 +270,7 @@ h1, h2, h3,
|
||||||
margin: 0!important;
|
margin: 0!important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.select2-dropdown {
|
||||||
|
display: inline-grid !important;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue