在非主键关系上加入和查询Django模型?

时间:2015-07-30 23:25:47

标签: django django-models

我有两个通过不是主键的字段逻辑相关的模型。是否可以在不引入select_related(…)列的情况下查询它们(例如ForeignKey)?

例如,考虑人为的模型:

class LogEntry(Model):
    source_name = CharField(…)
    log_message = CharField(…)

class LogSource(Model):
    name = CharField(…)
    domain = CharField(…)

我希望能够查询LogEntry,加入并过滤相关的LogSource(例如,我可以访问log_entry.source而无需其他查询):

LogEntry.objects
    .select_related(
        source=Join(LogSource, on="logsource.name = logentry.source_name")),
    )
    .filter(source__domain="example.com")

这是否可能而不引入ForeignKey

1 个答案:

答案 0 :(得分:5)

您应该可以extra()使用tables选项来执行此操作。

LogEntry.objects.extra(
    tables=['logsource'],
    where=['logsource.name=logentry.source_name',
           'logsource_domain="example.com"',
           ]
)

另一种选择是将source_name更改为外键,但指定db_columnto_field参数以使用现有列。我知道你说你不想添加外键,但它可能是可以接受的,因为它只更改模型,而不是数据库表中的列。但是,请注意Django可能想要创建外键约束。一个黑客就是伪造那个迁移,这样就不会在数据库中创建约束。

class LogEntry(Model):
    source_name = models.ForeignKey(db_column=source_name', to_field='name')

log_entry.source_name将成为LogSource个实例,log_entry.source_name_id将成为source_name列中存储的值。转换为外键后,将字段从source_name重命名为source可能是有意义的,但这不是必需的。