다 대다 목록 디스플레이 장고


91
class PurchaseOrder(models.Model):
    product = models.ManyToManyField('Product')
    vendor = models.ForeignKey('VendorProfile')
    dollar_amount = models.FloatField(verbose_name='Price')


class Product(models.Model):
   products = models.CharField(max_length=256)

   def __unicode__(self):
       return self.products

그 코드가 있습니다. 불행히도 오류는 admin.py에ManyToManyField

class PurchaseOrderAdmin(admin.ModelAdmin):
    fields = ['product', 'dollar_amount']
    list_display = ('product', 'vendor')

오류 내용 :

'PurchaseOrderAdmin.list_display [0]', 'product'는 지원되지 않는 ManyToManyField입니다.

내가 걸릴 때, 그것은 컴파일 'product'밖으로 list_display. 그래서 내가 어떻게 표시 할 수 있습니다 'product'에서 list_display그것을 오류를 부여하지 않고?

편집 : 아마도 더 나은 질문은 당신이 표시 어떻게 될 것 ManyToManyField으로 list_display?

답변:


171

직접 할 수 없을 수도 있습니다. 문서에서list_display

ManyToManyField 필드는 테이블의 각 행에 대해 별도의 SQL 문을 실행해야하기 때문에 지원되지 않습니다. 그럼에도 불구하고이 작업을 수행하려면 모델에 사용자 지정 메서드를 제공하고 해당 메서드의 이름을 list_display에 추가합니다. (list_display의 사용자 지정 메서드에 대한 자세한 내용은 아래를 참조하십시오.)

다음과 같이 할 수 있습니다.

class PurchaseOrderAdmin(admin.ModelAdmin):
    fields = ['product', 'dollar_amount']
    list_display = ('get_products', 'vendor')

    def get_products(self, obj):
        return "\n".join([p.products for p in obj.product.all()])

또는 모델 방법을 정의하고

class PurchaseOrder(models.Model):
    product = models.ManyToManyField('Product')
    vendor = models.ForeignKey('VendorProfile')
    dollar_amount = models.FloatField(verbose_name='Price')

    def get_products(self):
        return "\n".join([p.products for p in self.product.all()])

그리고 관리자 list_display

list_display = ('get_products', 'vendor')

이것은 정말 좋은 해결책처럼 보입니다. 감사합니다. 하지만 이제 ""product_id "열의 null 값이 null이 아닌 제약 조건을 위반한다는 오류 메시지가 나타납니다."이게 무슨 뜻인지 아십니까?
Mdjon26

3
이것은 데이터베이스를 무너 뜨리기 때문에 성능을 향상시키기 위해 select_related () 또는 prefetch_related ()로 어떻게 수행할까요?
Cloud Artisans

3
이런 경우의 최적화 문제는, 난 그냥 여전히 흥미로운 같은 문제가 있었다 당신은 단순히 최적화 구현할 수 있다는 것을 발견 get_queryset()당신을위한 방법을 ModelAdmin참조 stackoverflow.com/questions/12354099/...
GOETZ

1
@ SebastiánVansteenkiste 좋은 생각, 아마도 cached_property도움이 될 것입니다. 그러나 아마 그렇지 않을 것이라고 생각합니다. 최적화 된를 사용하는 get_queryset경우 예를 들어 Django 대신 SQL에서 제품을 연결하는 것과 같이 데이터에 주석을 달거나 사전 처리하고 쿼리 세트에 사용자 지정 데이터를 저장할 수 있습니다. 그런 다음 속성에 액세스 할 때 모든 행이 아니라 SQL에서 해당 논리를 한 번만 실행하면됩니다.
goetz

1
좋은 지적. 난 내 자신을 최적화하고 조사해야한다 get_queryset, 난 그냥 전체 문서를 읽고 주위 얻었다 (도 내가 일을해야 무엇을 충분히 간단한 예를 찾을 수 없음)하지 않은
세바스티안 Vansteenkiste

16

이 방법으로 할 수 있습니다. 다음 스 니펫을 친절하게 확인하세요.

class Categories(models.Model):
    """ Base category model class """

    title       = models.CharField(max_length=100)
    description = models.TextField()
    parent      = models.ManyToManyField('self', default=None, blank=True)
    when        = models.DateTimeField('date created', auto_now_add=True)

    def get_parents(self):
        return ",".join([str(p) for p in self.parent.all()])

    def __unicode__(self):
        return "{0}".format(self.title)

그리고 다음과 같이 admin.py 모듈 호출 방법에서 :

class categories(admin.ModelAdmin):
    list_display    = ('title', 'get_parents', 'when')
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.