如何在Django中执行此连接查询

14 投票
4 回答
60953 浏览
提问于 2025-04-15 11:34

在Django中,我有两个模型:

class Product(models.Model):
    name = models.CharField(max_length = 50)
    categories = models.ManyToManyField(Category)

class ProductRank(models.Model):
    product = models.ForeignKey(Product)
    rank = models.IntegerField(default = 0)

我把排名放在一个单独的表里,因为每次查看页面都会导致排名变化,我担心这么多的写入操作会让我的其他查询(大部分是读取操作)变得很慢。

我通过一个简单的查询获取了一些产品的列表:

cat = Category.objects.get(pk = 1)
products = Product.objects.filter(categories = cat)

现在我想获取这些产品的所有排名。我希望能一次性完成这个操作(使用SQL连接),想知道怎么用Django的查询机制来实现。

在Django中,正确的做法是什么呢?

4 个回答

2

可以在QuerySet中添加一个调用select_related()的方法,虽然我不太确定这个方法是否能同时获取两个方向的引用,但这很可能是正确的答案。

7

我还没检查过,不过:

products = Product.objects.filter(categories__pk=1).select_related()

应该能抓取到每一个实例。

18

在Django中可以做到这一点,不过你需要稍微调整一下你的模型结构:

class Product(models.Model):
    name = models.CharField(max_length=50)
    product_rank = models.OneToOneField('ProductRank')

class ProductRank(models.Model):
    rank = models.IntegerField(default=0)

现在,当你获取产品对象时,可以通过使用select_related()方法,来一次性获取与产品相关的排名信息:

Product.objects.filter([...]).select_related()

这样做会生成一个查询,通过连接的方式获取产品排名:

SELECT "example_product"."id", "example_product"."name", "example_product"."product_rank_id", "example_productrank"."id", "example_productrank"."rank" FROM "example_product" INNER JOIN "example_productrank" ON ("example_product"."product_rank_id" = "example_productrank"."id")

我需要把产品和产品排名之间的关系字段移动到产品模型中,因为看起来select_related()只会单向跟踪外键。

撰写回答