【问题标题】:Unnecessary join in django queryset of model with many-to-many field and intermediate table具有多对多字段和中间表的模型的django查询集中不必要的连接
【发布时间】:2019-06-17 04:09:37
【问题描述】:

当我尝试获取模型 FabricCategory 的所有对象时,它会返回一些重复项。我在 sql 查询中发现了不必要的 LEFT OUTER JOIN:

python manage.py shell_plus --print-sql

>>> FabricCategory.objects.all()
SELECT `product_fabriccategory`.`id`,
       `product_fabriccategory`.`price_impact`,
       `product_fabriccategory`.`code`,
       `product_fabriccategory`.`active`
  FROM `product_fabriccategory`
  LEFT OUTER JOIN `product_fabriccategoryfabric`
    ON (`product_fabriccategory`.`id` = `product_fabriccategoryfabric`.`fabriccategory_id`)
 ORDER BY `product_fabriccategoryfabric`.`position` ASC,
          `product_fabriccategoryfabric`.`fabriccategory_id` ASC
 LIMIT 21

这是我的设置:

class FabricCategoryFabric(models.Model):
    fabriccategory = models.ForeignKey(
        'FabricCategory', related_name='fabriccategory_fabrics', on_delete=models.DO_NOTHING, null=True)
    fabric = models.ForeignKey(
        'Fabric', related_name='fabriccategory_fabrics', on_delete=models.DO_NOTHING, null=True, blank=True)
    position = models.IntegerField(default=0)

    class Meta:
        ordering = ['position', 'fabriccategory_id']


class FabricCategory(models.Model):
    price_impact = models.FloatField(default=1)
    code = models.CharField(unique=True, max_length=50, null=True)
    active = models.BooleanField(default=True)
    fabrics = models.ManyToManyField(
        'Fabric', related_name='fabric_fabriccategory',
        through='FabricCategoryFabric',
        through_fields=('fabriccategory', 'fabric'))

    class Meta:
        verbose_name_plural = "fabric categories"
        ordering = ['fabriccategory_fabrics']

    def __str__(self):
        return str(self.price_impact)


class Fabric(models.Model):
    fabric_category = models.ForeignKey(
        FabricCategory, null=True, on_delete=models.DO_NOTHING)
    reference = models.CharField(unique=True, max_length=50)
    content = models.TextField(blank=True)
    thumbnail = models.CharField(max_length=50, blank=True)
    active = models.BooleanField(default=True)

    def __str__(self):
        return self.reference

    class Meta:
        ordering = ['fabric_fabriccategory']

有人遇到并解决过这个问题吗? 我正在使用: Django 2.1.1 mysqlclient 1.3.13 数据库引擎 django.db.backends.mysql

【问题讨论】:

    标签: python django orm django-orm django-2.1


    【解决方案1】:

    由于您指定了ordering = ['fabric_fabriccategory'],所有查询默认情况下都会连接到FabricCategoryFabric 的表。

    【讨论】:

    • 非常感谢,我完全忘记了这个,尝试了几十种不同的方法。
    猜你喜欢
    • 2018-10-06
    • 2011-10-27
    • 2013-05-17
    • 2011-04-07
    • 1970-01-01
    • 2020-06-16
    • 2022-11-01
    • 2019-08-19
    • 2018-02-09
    相关资源
    最近更新 更多