Сортировка в списке администратора django по пользовательскому полю в алфавитном порядке
У меня есть простое отношение магазин / продукт, и я хочу сортировать продукты в зависимости от названия магазина в алфавитном порядке.
модели:
class Store(models.Model):
name = models.CharField("name", max_length = 128)
class Product(models.Model):
number = models.PositiveIntegerField()
name = models.CharField("name", max_length = 128)
store = models.ForeignKey(Store, on_delete = models.CASCADE)
и в админке:
class ProductAdmin(admin.ModelAdmin):
list_display = ["number", "name", "get_store_name",]
def get_store_name(self, obj):
return f"""{obj.store.name}"""
Я знаю, что не могу использовать order_by
в пользовательских полях. Поэтому я подумал, что мне нужно переопределить метод get_queryset
, возможно? Я нашел множество примеров аннотации для подсчитанных или вычисленных чисел, но никогда для строк.
Вы можете аннотировать поле с условием в queryset и затем, установить его как ordering
в @admin.display
декораторе для вашего пользовательского поля.
from django.db.models import Case, F, When
class ProductAdmin(admin.ModelAdmin):
list_display = ["number", "name", "get_store_name"]
def get_queryset(self, request):
queryset = super().get_queryset(request)
queryset = queryset.annotate(
_store_name=Case(
When(store__show_name__isnull=True, then=F('store__name')),
default=F('store__show_name')),
),
)
return queryset
@admin.display(ordering='_store_name')
def get_store_name(self, obj):
if obj.store.show_name:
return obj.store.show_name
return obj.store.name
При такой реализации стандартная сортировка интерфейса администратора django будет работать для вашего столбца
Если вам нужна только сортировка по умолчанию, вы можете добавить ее в queryset перед возвратом в get_queryset()
queryset.order_by('_store_name')