Django模型过滤器并按特定列区分

Posted

技术标签:

【中文标题】Django模型过滤器并按特定列区分【英文标题】:Django model filter and do distinct by specific column 【发布时间】:2018-02-22 05:47:21 【问题描述】:

我有两个模型

class Category(models.Model):
    name= models.TextField(max_length=255)
    parent = models.ForeignKey('self', null=True, blank=True)

class Brand(models.Model):
    category = models.ForeignKey(Category)
    name= models.TextField(max_length=255)

例如:

类别

         name        parent
         -------      -------
         vehicle        0
         car            1 
         motorcycle     1 
         truck          1 
         bicycle        1
         fff            0
         ....

品牌

            name      category
            ----      --------- 
            BMW        car
            BMW        truck
            BMW        bicycle
            toyota     car
            mercedes   car
            mercedes   truck
            someThing  fff
            ....

我想创建一个按车辆过滤并按名称区分的品牌查询集。

所以我可以在我的模板中创建一个表单,该表单将有一个下拉过滤器,其中包含与车辆类别相关的所有品牌,并且名称不重复

            name     category
            ----     --------- 
            BMW       car
            toyota    car
            mercedes  truck

有没有什么方法可以用简单的方法来做,或者我需要为此编写一个函数吗?

我看到了一个例子Select DISTINCT individual columns in django? 但它返回一个ValuesQuerySet,我需要一个QuerySet,我不想使用仅在PostgreSQL 上支持的().distinct('someItem')

【问题讨论】:

【参考方案1】:

避免 QuerySet 中出现重复的最简单方法是在 Brand 和 Category 模型的名称字段中添加 unique constraint。这将首先阻止重复插入。

每当您尝试创建名称已存在于数据库中的品牌或类别时,该约束将导致抛出 IntegrityError。您可以使用ModelName.objects.get_or_create 而不是ModelName.objects.create() 来避免该错误。

【讨论】:

可以在数据库中为不同类别使用相同的品牌,但如果我想按品牌过滤,用户不需要在下拉重复名称中看到 这会加入品牌和类别,这可能会导致重复。 distinct 会以稍微昂贵的代价移除它们。 Category.objects.filter(brand__name__in=("BMW", "toyota")).distinct() 您可以通过 pk 查找品牌并将其传入:brands = Brand.objects.filter(name__in=( "BMW", "toyota")) Category.objects.filter(brand_id__in=brands) 我需要将品牌加入到类别中,因为它们是相关的。用户可以将项目添加到系统中,当他这样做时,他必须只选择与该类别相关的品牌,所以我向他显示与他所在类别相关的相关品牌,他可以按品牌过滤项目,类别,或类别和相关品牌

以上是关于Django模型过滤器并按特定列区分的主要内容,如果未能解决你的问题,请参考以下文章

两列连接后的 Django 查询集过滤器

Django ORM按两个相关模型的最大列值过滤

使用 Ajax 按钮过滤 Django 模型

在 Django 中使用继承过滤模型

Django Admin:如何过滤特定范围值的整数字段

过滤在特定时间之前或之后添加的 django 对象