Django admin, функция возврата полного имени в list_filter
Итак, я создал модель под названием Customers, которая имеет имя_первое, имя_последнее и dob (aka Date of Birth).
Я не хочу хранить полное_имя в поле, я просто хочу иметь возможность упорядочивать клиентов по их полному имени, а не по первому_* или последнему_*.
Я хотел сделать в модели функцию getFullName, которая возвращает имя и фамилию вместе, но Django выдал ошибку, сказав, что getFullName не ссылается на поле.
Есть идеи, как я могу это исправить, избегая наличия атрибута full_name, который устанавливается в методе сохранения?
Я также использую стандартную админку Django, просто потому что я люблю ее (особенно с Django-jet).
edit: источник в соответствии с запросом.
# models.py
class Customer(models.Model):
first_name = models.CharField(max_length=100, blank=False, verbose_name="First name", null=True)
last_name = models.CharField(max_length=100, blank=False, verbose_name="Last name", null=True)
dob = models.DateField(verbose_name="Date of Birth", blank=False, null=True)
def getFullName(self):
return "%s %s" %(self.first_name, self.last_name)
getFullName.short_description = "Full Name"
# admin.py
class CustomerAdmin(admin.ModelAdmin):
# here would be the list_filter = ('getFullName',), which threw the mentioned error.
# list_display = ('getFullName',) works just fine, but that is not what I want to achieve.
pass
admin.site.register(Customer, CustomerAdmin)
Вы можете сделать его свойством вместо метода это будет
@property
def getFullName(self):
return "%s %s" %(self.first_name, self.last_name)
тогда вы можете сделать пользовательский фильтр
class FullNameFilter(SimpleListFilter):
title = 'full name'
parameter_name = 'full_name'
def lookups(self, request, model_admin):
return (
('True', True),
('False', False)
)
def queryset(self, request, queryset):
if self.value():
# If full_name=True filter is activated
return queryset.filter(<Write your logic here>)
else:
# If full_name=True filter is activated
return queryset.filter(<Write your other logic>)
Чтобы иметь возможность сортировки по комбинированному полю, необходимо настроить набор запросов с аннотациями.
from django.contrib import admin
from django.db.models.functions import Concat
class CustomerAdmin(admin.ModelAdmin):
list_display = [
"pk",
"first_name",
"last_name",
"full_name",
"dob",
]
def get_queryset(self, request):
qs = self.model._default_manager.get_queryset()
qs = qs.annotate(full_name=Concat('first_name', 'last_name'))
ordering = self.get_ordering(request)
if ordering:
qs = qs.order_by(*ordering)
return qs
def full_name(self, obj):
return obj.full_name
full_name.admin_order_field = 'full_name'
full_name.short_description = 'Full Name'