我有两个通过不是主键的字段逻辑相关的模型。是否可以在不引入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 ?
答案 0 :(得分:5)
您应该可以extra()
使用tables
选项来执行此操作。
LogEntry.objects.extra(
tables=['logsource'],
where=['logsource.name=logentry.source_name',
'logsource_domain="example.com"',
]
)
另一种选择是将source_name
更改为外键,但指定db_column
和to_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
可能是有意义的,但这不是必需的。