模型.py
class Tdzien(models.Model):
dziens = models.SmallIntegerField(primary_key=True, db_column='DZIENS')
dzienrok = models.SmallIntegerField(unique=True, db_column='ROK')
class Tnogahist(models.Model):
id_noga = models.ForeignKey(Tenerg, primary_key=True, db_column='ID_ENERG')
dziens = models.SmallIntegerField(db_column='DZIENS')
我想要的是得到 id_noga 其中 dzienrok=1234。我知道 dziens 应该是
dziens = models.ForeignKey(Tdzien)
但事实并非如此,我无法改变这一点。通常我会使用类似的东西
Tnogahist.objects.filter(dziens__dzienrok=1234)
但我不知道如何在没有外键的情况下连接和过滤这些表。
据我所知,没有外键就没有连接,但您可以使用两个查询:
Tnogahist.objects.filter(dziens__in=Tdzien.objects.filter(dzienrok=1234))
可以通过执行原始 SQL 查询来连接两个表。但对于这种情况,它是相当令人讨厌的,所以我建议你重写你的 models.py。
您可以在此处查看如何执行此操作
它会是这样的:
from django.db import connection
def my_custom_sql(self):
cursor = connection.cursor()
cursor.execute("select id_noga
from myapp_Tnogahist a
inner join myapp_Tdzien b on a.dziens=b.dziens
where b.dzienrok = 1234")
row = cursor.fetchone()
return row
你能用
.extra
来做这个吗?来自https://docs.djangoproject.com/en/dev/ref/models/querysets/#extra:
哪里/桌子
您可以定义显式 SQL WHERE 子句 — 也许是为了执行 非显式连接——通过使用 where。您可以手动添加表 使用表的 SQL FROM 子句。
为@paul-tomblin 的答案提供更多背景信息,
值得一提的是 对于绝大多数 django 用户来说;最好的做法是实施传统的外键。 Django 强烈建议避免使用
extra()
表示“将此方法作为最后的手段”。然而,extra()
仍然优于使用Manager.raw()的原始查询或使用django.db.connection直接执行自定义SQL
这是一个如何使用 django 的 .extra() 方法实现此目的的示例:
Tnogahist.objects.extra(
tables = ['myapp_tdzien'],
where = [
'myapp_tnogahist.dziens=myapp_tdzien.dziens',
'myapp_tdzien.dzienrok=%s',
],
params = [1234],
)
与其他方法相比,使用
extra()
的主要吸引力在于它可以与 django 的查询集堆栈的其余部分(例如过滤器、排除、延迟、值和切片)很好地配合。所以你可以将它与传统的 django 查询逻辑一起插入。例如:Tnogahist.objects.filter(...).extra(...).values('id_noga')[:10]
如果选择两个模型的某些字段没有外键,可以使用以下方法。
#import
from django.db.models import Subquery, OuterRef
from django.db.models.expressions import RawSQL
#result
dziens_result = Tdzien.objects.filter(dzienrok=1234).annotate(
tno_dziens=Subquery(Tnogahist.objects.filter(dziens=OuterRef('dziens')).values('dziens')
)
).values_list('dziens', 'tno_dziens', 'dzienrok','id_noga')