python - Django基于另一个模型字段注释值
问题描述
我有这两个模型,案例和专业,就像这样:
class Case(models.Model):
...
judge = models.CharField()
....
class Specialty(models.Model):
name = models.CharField()
sys_num = models.IntegerField()
我知道这听起来像一个非常奇怪的结构,但试着告诉我:模型judge
中的字段Case
引用一个Specialty
实例sys_num
值(judge
是一个字符字段,但它总是带有一个整数)(每个Specialty
实例都有一个唯一的sys_num
)。因此,我可以使用以下方式获取Specialty
与特定Case
实例相关的名称:
my_pk = #some number here...
my_case_judge = Case.objects.get(pk=my_pk).judge
my_specialty_name = Specialty.objects.get(sys_num=my_case_judge)
我知道这听起来很奇怪,但我无法更改表的底层架构,只需使用 sql 和 Django 的 orm 解决它。
我的问题是:我想在已经调用的查询集中注释Specialty
名称。Cases
values()
我只是设法让它工作Case
,When
但它不是动态的。如果我添加更多Specialty
实例,我将不得不手动更改代码。
cases.annotate(
specialty=Case(
When(judge=0, then=Value('name 0 goes here')),
When(judge=1, then=Value('name 1 goes here')),
When(judge=2, then=Value('name 2 goes here')),
When(judge=3, then=Value('name 3 goes here')),
...
这可以动态完成吗?我查看了django 的查询参考文档,但无法使用那里指定的工具生成有效的解决方案。
解决方案
您可以使用子查询表达式执行此操作:
from django.db.models import OuterRef, Subquery
Case.objects.annotate(
specialty=Subquery(
Specialty.objects.filter(sys_num=OuterRef('judge')).values('name')[:1]
)
)
对于某些数据库,甚至可能需要强制转换:
from django.db.models import IntegerField, OuterRef, Subquery
from django.db.models.functions import Cast
Case.objects.annotate(
specialty=Subquery(
Specialty.objects.filter(sys_num=Cast(
OuterRef('judge'),
output_field=IntegerField()
)).values('name')[:1]
)
)
但是造型很差。通常最好使用 a ForeignKey
,这将保证judge
can 只指向一个有效的案例(因此引用完整性),将在字段上创建索引,并且它还将使 Django ORM 更有效,因为它允许更高级的查询使用(相对)小查询。
推荐阅读
- c++ - GetReturnValue().Set() 处的 Nodejs 插件错误
- apache - 如何在没有 mod_security 的情况下更改 Apache 的“服务器:”标头?
- python - 在 Python 中流式传输时同步音频和视频
- git - 克隆后留下的 Git 冲突标记
- python - Discord.py 循环打印用户多次?
- google-apps-script - 共享文件后 onSelectionChange 损坏
- node.js - 如何通过 ID 获取 json 数组中的数据?
- php - 如何在类函数的包含文件中声明 php supper global const?
- javascript - ASP.NET MVC 上的客户端验证
- android - Android工作室错误没有找到'app'的变体