如何在Django中加入查询

Fra*_*ger 11 python sql django

在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)
Run Code Online (Sandbox Code Playgroud)

我将排名放在一个单独的表中,因为页面的每个视图都会导致排名发生变化,我担心所有这些写入都会使我的其他(主要是读取)查询变慢.

Products从一个简单的查询中收集了一个列表:

cat = Category.objects.get(pk = 1)
products = Product.objects.filter(categories = cat)
Run Code Online (Sandbox Code Playgroud)

我现在想要获得这些产品的所有等级.我宁愿一次性完成所有操作(使用SQL连接),并且想知道如何使用Django的查询机制来表达它.

在Django中这样做的正确方法是什么?

Aym*_*ieh 14

这可以在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)
Run Code Online (Sandbox Code Playgroud)

现在,在获取Product对象时,您可以使用select_related()方法在一个查询中遵循一对一关系:

Product.objects.filter([...]).select_related()
Run Code Online (Sandbox Code Playgroud)

这将生成一个使用连接获取产品排名的查询:

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")
Run Code Online (Sandbox Code Playgroud)

我不得不将Product和ProductRank之间的关系字段移动到Product模型,因为它看起来像select_related()仅在一个方向上跟随外键.


Ale*_*Ale 5

我没有检查,但是:

products = Product.objects.filter(categories__pk=1).select_related()
Run Code Online (Sandbox Code Playgroud)

应该抓住每个实例。