Django:list_display ManyToManyField 排序

Kho*_*nix 4 django django-models django-admin

我有以下代码:

#models.py
class Repair(models.Model):
    products = models.ManyToManyField(Product)
    description = models.TextField()

    def products_list(self):
        return ', '.join([a.name for a in self.products.all()])

class Product(models.Model):
    name = models.CharField(max_length=50,blank=False)
    description = models.TextField(blank=True)


#admin.py
class RepairAdmin(admin.ModelAdmin):
    list_display = ('products_list', 'description')
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我使用带有连接的自定义模型字段来显示 ModelAdmin list_display 属性上的所有修复相关产品,这是正确的。

现在我的问题是:如何在 list_display 上使自定义字段排序?我只想按 ManyToMany relashiontship 上的第一项排序。我尝试在模型上使用以下代码:

products_list.admin_order_field = 'products__name'
Run Code Online (Sandbox Code Playgroud)

包括这一行,我可以激活字段排序,但它无法正常工作...当请求字段排序时,它会在表上显示与它具有的关系一样多的记录重复。

我一直在研究,我发现的最接近解决方案的是:

Django admin:如何按没有数据库字段的自定义 list_display 字段之一进行排序

但我没有看到将其应用于我的案例的正确方法。

pco*_*nel 5

您会看到“表上的重复记录与其所具有的关系一样多”,因为'products__name'正在获取ProductRepair.

如果您想按productsModelAdmin 中ManyToMany 关系中的第一项排序,那么制作property获取第一个产品的a 可能是最简单的——然后将其分配给admin_order_field

class Repair(models.Model):
    products = models.ManyToManyField(Product)
    description = models.TextField()

    def products_list(self):
        return ', '.join([a.name for a in self.products.all()])

    # add a property which gets the name of the first product
    @property
    def first_product(self):
        self.products.all().first()  # first() was added in 1.6, otherwise use [0]


class RepairAdmin(admin.ModelAdmin):
    list_display = ('products_list', 'description')
    # use that property to only get the first product when ordering
    products_list.admin_order_field = 'first_product__name'
Run Code Online (Sandbox Code Playgroud)