Django关系查找未创建预期查询

2024-06-28 16:15:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用的是django1.11.6、python3.4.2、postgresql、pycharm4.5.2和windows10(仅用于开发目的)

目标是利用Djangodocs中的“跨越关系的查找”

# 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)
....

仅供参考,这些表在模型名称前面加了app名称,外键在外键列名后面加了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. 为什么查询会忽略筛选器中的页类型关系?查看打印查询的结果和视图中的过滤器。我还应该补充一点,我在AlphaBoard.fk\u page\u type中有一个相关的\u name=“fk\u page\u type”,但我删除了它。所以接下来的一个问题是,为什么它仍然选择相关的名称
  2. 如何使用文档中的“关系”来获得预期的结果
  3. 有没有办法指定联接类型

Tags: alphaidtrueautoonmodelstypepage
1条回答
网友
1楼 · 发布于 2024-06-28 16:15:20

由于page_typeAlphaType模型的主键,并且它的值只写在AlphaBoard表的fk_page_type列中,因此不需要联接:

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

相关问题 更多 >