development

Django Admin : 데이터베이스 필드가없는 사용자 정의 list_display 필드 중 하나를 기준으로 정렬하는 방법

big-blog 2020. 7. 26. 11:35
반응형

Django Admin : 데이터베이스 필드가없는 사용자 정의 list_display 필드 중 하나를 기준으로 정렬하는 방법


# admin.py
class CustomerAdmin(admin.ModelAdmin):  
    list_display = ('foo', 'number_of_orders')

# models.py
class Order(models.Model):
    bar = models.CharField[...]
    customer = models.ForeignKey(Customer)

class Customer(models.Model):
    foo = models.CharField[...]
    def number_of_orders(self):
        return u'%s' % Order.objects.filter(customer=self).count()  

고객에 따라 어떻게 고객을 분류 number_of_orders할 수 있습니까?

admin_order_field데이터베이스 필드를 정렬해야하므로이 속성을 사용할 수 없습니다. Django는 기본 DB를 사용하여 정렬을 수행 할 수 있습니까? 주문 수를 포함하는 집계 필드를 작성하는 것은 여기에서 과도한 것으로 보입니다.

재미있는 점 : 브라우저에서 손으로 URL을 변경 하여이 열을 정렬하면 예상대로 작동합니다!


이 문제에 대한 Greg의 솔루션을 좋아했지만 관리자에서 동일한 작업을 직접 수행 할 수 있음을 지적하고 싶습니다.

from django.db import models

class CustomerAdmin(admin.ModelAdmin):
    list_display = ('number_of_orders',)

    def get_queryset(self, request):
    # def queryset(self, request): # For Django <1.6
        qs = super(CustomerAdmin, self).get_queryset(request)
        # qs = super(CustomerAdmin, self).queryset(request) # For Django <1.6
        qs = qs.annotate(models.Count('order'))
        return qs

    def number_of_orders(self, obj):
        return obj.order__count
    number_of_orders.admin_order_field = 'order__count'

이 방법으로 관리자 인터페이스 내부에만 주석을 달 수 있습니다. 당신이하는 모든 쿼리가 아닙니다.


나는 이것을 테스트하지 않았지만 (작동하는지 알고 싶습니다) Customer집계 된 주문 수를 포함 하는 사용자 정의 관리자를 정의 한 다음 admin_order_field해당 집계 로 설정 하는 것은 어떻 습니까?

from django.db import models 


class CustomerManager(models.Manager):
    def get_query_set(self):
        return super(CustomerManager, self).get_query_set().annotate(models.Count('order'))

class Customer(models.Model):
    foo = models.CharField[...]

    objects = CustomerManager()

    def number_of_orders(self):
        return u'%s' % Order.objects.filter(customer=self).count()
    number_of_orders.admin_order_field = 'order__count'

편집 : 나는이 아이디어를 방금 테스트했으며 완벽하게 작동합니다-django admin 서브 클래스가 필요하지 않습니다!


내가 생각할 수있는 유일한 방법은 현장을 비정규 화하는 것입니다. 즉, 파생 된 필드와 동기화되도록 업데이트되는 실제 필드를 만듭니다. 나는 보통 비정규 화 된 필드 또는 모델에서 파생 된 모델로 eith에 저장을 재정 의하여이를 수행합니다.

# models.py
class Order(models.Model):
    bar = models.CharField[...]
    customer = models.ForeignKey(Customer)
    def save(self):
        super(Order, self).save()
        self.customer.number_of_orders = Order.objects.filter(customer=self.customer).count()
        self.customer.save()

class Customer(models.Model):
    foo = models.CharField[...]
    number_of_orders = models.IntegerField[...]

참고 URL : https://stackoverflow.com/questions/2168475/django-admin-how-to-sort-by-one-of-the-custom-list-display-fields-that-has-no-d

반응형