Django关系查找没有创建预期的查询

时间:2017-11-01 01:48:09

标签: python django postgresql

我使用的是Django 1.11.6,python 3.4.2,postgresql,PyCharm 4.5.2和windows 10(仅用于开发目的)。

目标是利用跨越关系的'查找' 来自Django docs

# models
class AlphaType(models.Model):
    page_type = models.CharField(max_length=50, primary_key=True, null=False)
    created_on = models.DateTimeField(auto_now_add=True)
    modified_on = models.DateTimeField(auto_now=True)

class AlphaBoard(models.Model):
    title = models.CharField(max_length=50)
    alpha_text = models.TextField(max_length=30000)
    created_on = models.DateTimeField(auto_now_add=True)
    modified_on = models.DateTimeField(auto_now=True)
    fk_page_type = models.ForeignKey(AlphaType, on_delete=models.CASCADE, default='general')

#views
....
    q = AlphaBoard.objects.filter(fk_page_type__page_type='general')
    print(q.query)
....

只是fyi,这些表的应用名称前面加上了型号名称,外键的名称是' id'附加到外键列名。

查询结果打印。

SELECT 
    "alpha_alphaboard"."id", "alpha_alphaboard"."title", 
    "alpha_alphaboard"."alpha_text", "alpha_alphaboard"."created_on", 
    "alpha_alphaboard"."modified_on", "alpha_alphaboard"."fk_page_type_id" 
FROM 
    "alpha_alphaboard" 
WHERE 
    "alpha_alphaboard"."fk_page_type_id" = "general"

我的期待。

SELECT 
    "alpha_alphaboard"."id", "alpha_alphaboard"."title", 
    "alpha_alphaboard"."alpha_text", "alpha_alphaboard"."created_on", 
    "alpha_alphaboard"."modified_on", "alpha_alphaboard"."fk_page_type_id" 
FROM 
    "alpha_alphaboard" 
INNER JOIN "alpha_alphaboard" ON "alpha_alphatype"
    "alpha_alphaboard"."fk_page_type_id" = "alpha_alphatype"."page_type"
WHERE
    "alpha_alphatype"."page_type" = "general"

问题

  1. 为什么查询忽略了过滤器的page_type关系?查看打印查询的结果和视图中的过滤器。我还应该补充一点,我有一个related_name =" fk_page_type"在AlphaBoard.fk_page_type中,但我删除了它。因此,后续问题是为什么它还在拿起related_name?
  2. 你如何使用"关系"从文档中获得预期?
  3. 有没有办法指定连接类型?

1 个答案:

答案 0 :(得分:0)

由于page_typeAlphaType模型的主键,其值只写在fk_page_type表的AlphaBoard列中,因此不需要连接:< / p>

q = AlphaBoard.objects.filter(fk_page_type__page_type='general')

相同
q = AlphaBoard.objects.filter(fk_page_type_id='general')

您在过滤器中使用的相关模型的字段是在主表中写入的确切外键值。

至于related_name,它用于访问反向关系:

class AlphaBoard(models.Model):
    fk_page_type = models.ForeignKey(AlphaType, on_delete=models.CASCADE, related_name='boards')

t = AlphaType(...)
boards = t.boards.all()  # gives all boards with type t
boards = t.alphaboard_set.all()  # default: lowermodelname_set