-
Notifications
You must be signed in to change notification settings - Fork 0
/
admin.py
75 lines (59 loc) · 2.57 KB
/
admin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
from django.contrib import admin
from django.contrib.admin import SimpleListFilter, ModelAdmin
from django.core.cache import caches
from django.db.models import Model, QuerySet
from .util import is_function
def foreign_field(field_name):
def accessor(obj):
val = obj
for part in field_name.split('__'):
val = getattr(val, part)
if val is None:
return None
return val if not is_function(val) else val()
accessor.__name__ = field_name
return accessor
ff = foreign_field
class YesNoFilter(SimpleListFilter):
def lookups(self, request, model_admin):
return [
('1', 'yes'),
('0', 'no'),
]
def queryset(self, request, queryset) -> QuerySet:
if self.value():
queryset = self.queryset_yes_no(request, queryset, self.value() == '1')
return queryset
def queryset_yes_no(self, request, queryset, is_yes) -> QuerySet:
raise NotImplementedError
# noinspection PyMethodMayBeStatic
class CachedFieldListFilter(SimpleListFilter):
def __init__(self, request, params, model, model_admin, ttl=24 * 60 * 60):
self.model = model
self.ttl = ttl
self.null_key, self.null_value = self.null_key_value()
super().__init__(request, params, model, model_admin)
def lookups(self, request, model_admin):
cache = caches['default']
cache_key = f'field_list_filter.{self.model.__module__}.{self.model.__name__}.{self.field_name}'
values = cache.get(cache_key)
if values is None:
values = self.model.objects.values_list(self.field_name).distinct().order_by(self.field_name).all()
values = [v[0] for v in values]
has_none = None in values
values = [(self.value_to_key(v), str(v)) for v in values if v is not None]
if has_none:
values.append((self.null_key, self.null_value))
cache.set(cache_key, values, self.ttl)
return values
def null_key_value(self): return 'null', '-'
def value_to_key(self, v): return str(v)
def key_to_filter_value(self, v): return v
def queryset(self, request, queryset):
if self.value():
field_value = self.key_to_filter_value(self.value()) if self.value() != self.null_key else None
params = {self.field_name: field_value}
queryset = queryset.filter(**params)
return queryset
def register_admin(clazz: type[Model], admin_class: type[ModelAdmin] = None):
admin.site.register(clazz, admin_class if admin_class else clazz.Admin)