在非主键关系上加入和查询Django模型? [英] Join and query Django models on non-primary-key relationship?

查看:132
本文介绍了在非主键关系上加入和查询Django模型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've got two models that are logically related through a field that is not the primary key. Is it possible to query them (ex, select_related(…)) without introducing a ForeignKey column?

例如,考虑人为模型:

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

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

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

I would like to be able to query LogEntry, joining in and filtering on the related LogSource (ex, so I can access log_entry.source without additional queries):

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

是否可能在不引入ForeignKey的情况下?

Is this possible without introducing a ForeignKey?

推荐答案

您应该能够o通过使用 extra() tables 选项。

You should be able to do this by using extra() with the tables option.

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

另一种选择是更改 source_name 到外键,但指定 db_column to_field 参数以使用现有列。我知道您说过您不想添加外键,但这是可以接受的,因为它仅更改模型,而不更改数据库表中的列。但是,请注意,Django可能要创建外键约束。一种破解方法是伪造该迁移,以便不在数据库中创建约束。

Another option is to change source_name to a foreign key, but specify the db_column and to_field arguments to use the existing columns. I know that you said that you didn't want to add a foreign key, but it might be acceptable because it only changes the models, not the columns in the database tables. However, be aware that Django might want to create a foreign key constraint. One hack would be to fake that migration so that the constraint isn't created in the db.

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 可能很有意义,但这不是必需的。

log_entry.source_name would then be the LogSource instance, and log_entry.source_name_id would be the value stored in the source_name column. It might make sense to rename the field from source_name to source after converting to a foreign key, but that's not necessary.

这篇关于在非主键关系上加入和查询Django模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆