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'
Вернуться на верх