many-to-many in list display django

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

def __unicode__(self):
return self.products


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

I have that code. Unfortunately, the error comes in admin.py with the ManyToManyField

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

The error says:

'PurchaseOrderAdmin.list_display[0]', 'product' is a ManyToManyField which is not supported.

However, it compiles when I take 'product' out of list_display. So how can I display 'product' in list_display without giving it errors?

edit: Maybe a better question would be how do you display a ManyToManyField in list_display?

79453 次浏览

你可能不能直接做到这一点

ManyToManyField 字段不受支持,因为这将需要 对表中的每一行执行单独的 SQL 语句 尽管如此,如果希望这样做,请给您的模型一个自定义方法,然后添加 该方法的名称设置为 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()])

OR 定义一个模型方法,并使用它

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()])

and in the admin list_display

list_display = ('get_products', 'vendor')

这样你就可以做到这一点,请检查下面的代码片段:

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')

如果您想保存额外的查询,您可以在 get_queryset方法中使用 prefetch_related,如下所示:

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


def get_queryset(self, request):
qs = super().get_queryset(request)
return qs.prefetch_related('product')


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

根据 医生,通过这种方式,只需要一个额外的查询来获取所有 PurchaseOrder实例的相关 Product项,而不是每个 PurchaseOrder实例需要一个查询。