列表中的多对多显示django

Mdj*_*n26 68 python django admin django-admin django-queryset

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
Run Code Online (Sandbox Code Playgroud)

我有那个代码.不幸的是,错误来自admin.py中ManyToManyField

class PurchaseOrderAdmin(admin.ModelAdmin):
    fields = ['product', 'dollar_amount']
    list_display = ('product', 'vendor')
Run Code Online (Sandbox Code Playgroud)

错误说:

'PurchaseOrderAdmin.list_display [0]','product'是不受支持的ManyToManyField.

然而,当我把它编译'product'出来的list_display.那么如何'product'list_display不给出错误的情况下显示呢?

编辑:也许一个更好的问题是你如何显示ManyToManyFieldlist_display

kar*_*ikr 138

您可能无法直接执行此操作.从文档中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()])
Run Code Online (Sandbox Code Playgroud)

或者定义一个模型方法,然后使用它

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()])
Run Code Online (Sandbox Code Playgroud)

在管理员 list_display

list_display = ('get_products', 'vendor')
Run Code Online (Sandbox Code Playgroud)

  • 万一优化问题仍然很有趣,我也遇到了同样的问题,发现您可以为您的ModelAdmin简单地实现优化的get_queryset()方法,请参阅/sf/ask/864786961/ / override-default-queryset-in-django-admin / 12354293#12354293 (3认同)
  • 由于这使数据库瘫痪,您将如何使用select_related()或prefetch_related()来提高性能? (2认同)

Luc*_*s B 18

如果你想节省额外的查询,你可以在方法中使用prefetch_lated ,get_queryset如下所示:

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()])
Run Code Online (Sandbox Code Playgroud)

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


小智 10

通过这种方式,您可以查看以下代码段:

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)
Run Code Online (Sandbox Code Playgroud)

并在您的admin.py模块调用方法如下:

class categories(admin.ModelAdmin):
    list_display    = ('title', 'get_parents', 'when')
Run Code Online (Sandbox Code Playgroud)