【问题标题】:Django filter() by ForeignKey returns incorrect querysetForeignKey 的 Django filter() 返回不正确的查询集
【发布时间】:2020-08-28 14:17:51
【问题描述】:

我有两个模型,Product 模型通过 ForeignKey 连接到 ProductGroupProduct 模型也有一个名为 ForeignKey 的字段 shop

class ProductGroup(models.Model):
    name = models.CharField(max_length=64)
    vat_rate = models.ForeignKey(VatRate, verbose_name="VAT in percent", related_name='product_group_vat_rates',
                                 on_delete=models.CASCADE)


class Product(models.Model):
    product_id = models.CharField(max_length=128, blank=True, null=True)
    name = models.CharField(max_length=128)
    shop = models.ForeignKey(Shop, on_delete=models.CASCADE, related_name="product_shop")
    product_group = models.ForeignKey(ProductGroup, on_delete=models.CASCADE, related_name="product")
    price = models.DecimalField(max_digits=7, decimal_places=2, blank=True, null=True, default=0)
    cost_price = models.DecimalField(max_digits=7, decimal_places=2, blank=True, null=True, default=0)
    stock_amount = models.IntegerField(default=0, blank=True, null=True,
                                       help_text=_('Product amount in stock'))
    barcode = models.CharField(max_length=64, blank=True)
    is_active = models.BooleanField(default=True)

假设,我有两个Product 实例,连接到特定商店,还有一个ProductGroup,连接到这两个Product 实例

所以现在我想获取与特定 shop 实例相关的所有 ProductGroup 实例。

我做什么:

product_group_list = ProductGroup.objects.filter(product__shop=shop_inst)

我想我会得到什么:

<QuerySet [<ProductGroup: Product Group test product group>]>

但是,不幸的是,我明白了:

<QuerySet [<ProductGroup: Product Group test product group>, <ProductGroup: Product Group test product group>]>

所以它返回给我这两个连接到Product 实例的ProductGroup 实例的查询集。

如何改进对 DB 的查询以仅获取一个连接到该商店的 ProductGroup 实例? (因为数据库中只有一条记录为ProductGroup

【问题讨论】:

  • 您使用的是 PostgresSQL 还是 MySQL? .distinct() 仅适用于 PostgresSQL。
  • 我正在使用 MySQL
  • 抱歉——我认为我的评论具有误导性。过去我认为 distinct 在 MySQL (stackoverflow.com/questions/12402923/…) 上不起作用。也许我误读了什么。

标签: python sql django django-models orm


【解决方案1】:

由于JOINing,它多次返回相同ProductCategory,你可以使用.distinct()

product_group_list = ProductGroup.objects.filter(product__shop=shop_inst)<b>.distinct()</b>

【讨论】:

    【解决方案2】:

    在查询中使用distinct 以消除重复项

    distinct(*fields)

    返回一个在其 SQL 查询中使用 SELECT DISTINCT 的新 QuerySet。 这会消除查询结果中的重复行。

    默认情况下,QuerySet 不会消除重复行。在实践中, 这很少是一个问题,因为简单的查询,例如 Blog.objects.all() 不引入重复结果的可能性 行。但是,如果您的查询跨越多个表,则有可能 在评估 QuerySet 时得到重复的结果。那时你会 使用 distinct()。

    product_group_list = ProductGroup.objects.filter(product__shop=shop_inst).distinct()
    

    【讨论】:

      猜你喜欢
      • 2018-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多