[英]I need to convert raw MySQL query to Django ORM query
I have models.py that represent below: 我有表示以下内容的models.py:
from django.db import models
from django.db.models.signals import post_save
# Create your models here.
from django.http import request
class Task(models.Model):
created = models.DateTimeField(auto_now_add=True)
description = models.CharField(max_length=512)
cost = models.DecimalField(decimal_places=2, max_digits=8)
def __str__(self):
return self.description + "-" + str(self.cost)
class TaskStatus(models.Model):
STATUS = (
(0, 'Created'),
(1, 'Taken'),
(2, 'Reissued'),
(3, 'On approve'),
(4, 'Done'),
)
task_id = models.IntegerField()
created = models.DateTimeField(auto_now_add=True)
status = models.PositiveSmallIntegerField(choices=STATUS, default=0)
def __str__(self):
return str(self.task_id) + ' ' + str(self.status)
def create_status(sender, instance, **kwargs):
if kwargs['created']:
task_status = TaskStatus.objects.create(task_id=instance.id)
post_save.connect(create_status, sender=Task)
I have to translate that mysql query to django ORM query. 我必须将mysql查询转换为Django ORM查询。 I got stack on this for 2 days.
我在上面堆了2天。 And please suggest me some useful links to understand how to perform.
并请建议我一些有用的链接以了解如何执行。
SELECT t.created,
t.description,
(SELECT MAX(s.created)
FROM task_statuses s
WHERE s.task_id = t.id AND s.status_type = 3
GROUP BY s.task_id) as task_on_approve
FROM task t
WHERE t.created BETWEEN '2019-04-01 00:00:00' AND '2019-04-30 23:59:59';
Take a look at the Django docs for Subquery
. 看看
Subquery
的Django文档。 Link . 链接 。
In a nutshell, this is what you're looking for: 简而言之,这就是您想要的:
from django.db import models
Task.objects.filter(created__gte='2019-04-01', created__lt='2019-05-01').annotate(task_on_approve=models.Subquery(TaskStatus.objects.filter(task_id=models.OuterRef('id'), status_type=3).order_by('-created').values('created')[:1], output_field=models.DateTimeField())).values('created', 'description', 'task_on_approve')
Try this. 尝试这个。 I am tested this code 100% working.
我已对此代码进行了100%的测试。
from datetime import datetime
from datetime import timezone
from django.core.management.base import BaseCommand, CommandError
from django.db.models import Avg, Max, Min, Sum, DateTimeField
from django.db.models import OuterRef, Subquery
from app.models import Task, TaskStatus
class Command(BaseCommand):
def handle(self, *args, **options):
sub_query = TaskStatus.objects\
.annotate(max_created_date=Max('created'))\
.filter(\
task_id=OuterRef('pk'),
status=3
)
from_datetime = datetime.strptime('2019-04-01 00:00:00', '%Y-%m-%d %H:%M:%S').replace(tzinfo=timezone.utc)
to_datetime = datetime.strptime('2019-04-30 23:59:59', '%Y-%m-%d %H:%M:%S').replace(tzinfo=timezone.utc)
query = Task.objects.annotate(
task_on_approve=Subquery(
sub_query.values('max_created_date')[:1],
output_field=DateTimeField()
)
).filter(
created__range=[
from_datetime,
to_datetime
]
)
print(query.query)
self.stdout.write('Done.')
Output 输出量
SELECT "app_task"."id", "app_task"."created", "app_task"."description", "app_task"."cost", (SELECT MAX(U0."created") AS "max_created_date" FROM "app_taskstatus" U0 WHERE (U0."status" = 3 AND U0."task_id" = ("app_task"."id")) GROUP BY U0."id", U0."task_id", U0."created", U0."status" LIMIT 1) AS "task_on_approve" FROM "app_task" WHERE "app_task"."created" BETWEEN 2019-04-01 00:00:00 AND 2019-04-30 23:59:59
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.