【问题标题】:Django ORM SELECT with join带有连接的 Django ORM SELECT
【发布时间】:2011-12-15 23:23:13
【问题描述】:

django 中的模型:

class Key(models.Model):
    id     = models.AutoField(primary_key=True, blank=True)
    name   = models.CharField(max_length=50)


class Record(models.Model):
    id         = models.AutoField(primary_key=True, blank=True)
    project_id = models.IntegerField()
    name       = models.CharField(max_length=50)


class Value(models.Model):
    id        = models.AutoField(primary_key=True, blank=True)
    record    = models.ForeignKey(Record)
    key       = models.ForeignKey(Key)
    value     = models.CharField(max_length=255)

我需要从数据库中选择这些数据:

NAME (from record)
and fields related with this record
[NAME (from key), VALUE (from value)]
[NAME (from key), VALUE (from value)]
[...]

我可以使用 django ORM 进行选择吗? (例如在 SQL 中选择看起来像这样)

SELECT
    `keeper_record`.`id` AS `record_id`,
    `keeper_record`.`name` AS `name`,
    `keeper_record`.`desc` AS `desc`,
    `keeper_key`.`name` AS `key_name`,
    `keeper_key`.`desc` AS `key_desc`,
    `keeper_value`.`value` AS `value_value`
FROM `keeper_record`
JOIN `keeper_value` ON `keeper_record`.`id` = `keeper_value`.`record_id`
JOIN `keeper_key` ON `keeper_key`.`id` = `keeper_value`.`key_id`
WHERE record_id = id

【问题讨论】:

    标签: python django django-models django-orm


    【解决方案1】:

    以下选择与特定记录 id 相关的值。然后您可以按照外键获取相关记录和键。使用select_related 可以最大限度地减少数据库查找。

    # Select all values related to a record in your view
    record = Record.objects.get(pk=record_id)
    values = Value.objects.filter(record=record).select_related()
    
    # In your template
    {% for value in values %}
    {{ value.record.name }} - {{ value.key.name }} - {{ value.value }}
    {% endfor %}
    

    选择多条记录

    在您的 sql 中,您有 WHERE record_id = 1,所以我展示了如何获取特定记录的所有值。您还可以在一个查询中选择多个记录的值。

    # filter all records which belong to the project with `project_id=1`
    records = Record.objects.filter(project_id=1)
    # select all values that belong to these records
    values = Value.objects.filter(record__in=records).select_related().order_by('record')
    

    【讨论】:

    • 我已经正确理解,对于每条记录都需要一个额外的查询来选择值,如果我想选择所有(或少数)记录,我需要在循环中选择值?
    • 我已经更新了选择多条记录的答案。希望对您有所帮助。
    【解决方案2】:

    应该相对简单,因为您已经将外键绑定在一起。

    Record.objects.select_related().filter(id = variable_that_stores_id)
    

    您可以将其与only 结合使用,以限制您想要恢复的字段。

    【讨论】:

    • select_related 在这里不起作用,因为它不遵循外键“向后”。
    • 我明白了。自从我的帖子以来,问题似乎发生了一些变化,但无论它是不正确还是不完整。
    猜你喜欢
    • 2019-08-12
    • 2018-10-10
    • 2014-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-22
    • 2020-05-18
    相关资源
    最近更新 更多