如何将此原始查询转换为 Django ORM
How to translate this raw query to Django ORM
我有一个模型,其中包含候选人、语言和语言级别实体:
class Candidate(models.Model):
user = models.ForeignKey(MyUser)
telephone = models.CharField(max_length=20, unique=True)
postcode = models.CharField(max_length=10)
class Language(models.Model):
name = models.CharField(max_length=50)
class LanguageLevel(models.Model):
candidate = models.ForeignKey(Candidate)
language = models.ForeignKey(Language)
level = models.IntegerField(max_length=1, choices=LANGUAGE_LEVEL, default=0)
我的原始查询是:
SELECT c.id, COUNT(c.id) as total
FROM candidates as c
JOIN language_level as ll ON ll.candidate_id=c.id
JOIN languages as l ON ll.language_id=l.id
WHERE ((ll.level >=1 AND l.id = 1 ) OR
(ll.level >=1 AND l.id = 2 ) OR
(ll.level >=1 AND l.id = 3 ) OR
(ll.level >=3 AND l.id = 4 ) OR
(ll.level >=3 AND l.id = 5 ) OR
(ll.level >=2 AND l.id = 6 ))
GROUP By c.id
我需要能够按总计字段对结果进行排序,我还需要能够在模板中显示该总计。我需要以某种方式创建一个更大的对象列表,将这 3 个实体 + 分组依据组合起来。
知道什么是最好的方法吗?我尝试获取候选人的 ID 并只执行 Candidates.objects.find(id__in = ids) 但以后没有办法对此进行排序。
提前致谢
我真的不明白你的 SQL 是如何做到你在评论中描述的。但是,此代码的作用与该描述类似。
from django.db.models import Max
Candidate.objects.filter(
languagelevel__language__name__in=['English', 'Spanish'],
languagelevel__level__gte=2
).annotate(max_level=Max('languagelevel__level')).order_by('max_level')
Candidate.objects.filter(
Q(Q(languagelevel__language__id__in=(1, 2, 3)) & Q(languagelevel__language__level__gte=1)) |
Q(Q(languagelevel__language__id__in=(4, 5)) & Q(languagelevel__language__level__gte=3)) |
Q(Q(languagelevel__language__id=6) & Q(languagelevel__language__level__gte=2))
)).values('id').annotate(total=Count('id'))
values
只会 return 每个候选人的 id
计算出的总数为 total
.
如果你想获取所有字段(不仅仅是id),你可以删除.values('id')
为:
Candidate.objects.filter(
Q(Q(languagelevel__language__id__in=(1, 2, 3)) & Q(languagelevel__language__level__gte=1)) |
Q(Q(languagelevel__language__id__in=(4, 5)) & Q(languagelevel__language__level__gte=3)) |
Q(Q(languagelevel__language__id=6) & Q(languagelevel__language__level__gte=2))
)).annotate(total=Count('id'))
我有一个模型,其中包含候选人、语言和语言级别实体:
class Candidate(models.Model):
user = models.ForeignKey(MyUser)
telephone = models.CharField(max_length=20, unique=True)
postcode = models.CharField(max_length=10)
class Language(models.Model):
name = models.CharField(max_length=50)
class LanguageLevel(models.Model):
candidate = models.ForeignKey(Candidate)
language = models.ForeignKey(Language)
level = models.IntegerField(max_length=1, choices=LANGUAGE_LEVEL, default=0)
我的原始查询是:
SELECT c.id, COUNT(c.id) as total
FROM candidates as c
JOIN language_level as ll ON ll.candidate_id=c.id
JOIN languages as l ON ll.language_id=l.id
WHERE ((ll.level >=1 AND l.id = 1 ) OR
(ll.level >=1 AND l.id = 2 ) OR
(ll.level >=1 AND l.id = 3 ) OR
(ll.level >=3 AND l.id = 4 ) OR
(ll.level >=3 AND l.id = 5 ) OR
(ll.level >=2 AND l.id = 6 ))
GROUP By c.id
我需要能够按总计字段对结果进行排序,我还需要能够在模板中显示该总计。我需要以某种方式创建一个更大的对象列表,将这 3 个实体 + 分组依据组合起来。
知道什么是最好的方法吗?我尝试获取候选人的 ID 并只执行 Candidates.objects.find(id__in = ids) 但以后没有办法对此进行排序。
提前致谢
我真的不明白你的 SQL 是如何做到你在评论中描述的。但是,此代码的作用与该描述类似。
from django.db.models import Max
Candidate.objects.filter(
languagelevel__language__name__in=['English', 'Spanish'],
languagelevel__level__gte=2
).annotate(max_level=Max('languagelevel__level')).order_by('max_level')
Candidate.objects.filter(
Q(Q(languagelevel__language__id__in=(1, 2, 3)) & Q(languagelevel__language__level__gte=1)) |
Q(Q(languagelevel__language__id__in=(4, 5)) & Q(languagelevel__language__level__gte=3)) |
Q(Q(languagelevel__language__id=6) & Q(languagelevel__language__level__gte=2))
)).values('id').annotate(total=Count('id'))
values
只会 return 每个候选人的 id
计算出的总数为 total
.
如果你想获取所有字段(不仅仅是id),你可以删除.values('id')
为:
Candidate.objects.filter(
Q(Q(languagelevel__language__id__in=(1, 2, 3)) & Q(languagelevel__language__level__gte=1)) |
Q(Q(languagelevel__language__id__in=(4, 5)) & Q(languagelevel__language__level__gte=3)) |
Q(Q(languagelevel__language__id=6) & Q(languagelevel__language__level__gte=2))
)).annotate(total=Count('id'))