微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用JOIN表达式翻译查询以及与Django ORM的通用关系

如何解决使用JOIN表达式翻译查询以及与Django ORM的通用关系

经过一天的苦苦挣扎,我终于解决了。尽管它不会从上方产生相同的查询,并且效率不高(因为它在查询事件中选择了所有喜欢的事物),但似乎这是在ORM中执行此操作的唯一好方法

from django.db.models import Case, When, F

Event.objects.filter( \
        Q(business__manager=person) | \
        Q(likes__person=person)) \
    .order_by( \
        Case( \
            When(likes__person=person, then=F('likes__date')), \
            default=F('when')) \
    .desc())

这是它产生的sql

SELECT event.*
FROM event
INNER JOIN
    business
    ON (event.business_id = business.id)
LEFT OUTER JOIN
    'like'
    ON (event.id = object_id AND content_type_id = 17)
WHERE (business.manager_id = 2 OR 'like'.person_id = 2)
ORDER BY CASE
    WHEN 'like'.person_id = 2 THEN 'like'.date
    ELSE event.'when'
END DESC;

解决方法

class Business(models.Model):
    manager = models.ForeignKey(User,on_delete=models.CASCADE)
    #...

class Event(models.Model):
    business = models.ForeignKey(Business,on_delete=models.CASCADE)

    text = models.TextField()
    when = models.DateTimeField()
    likes = GenericRelation('Like')

class Like(models.Model):
    person = models.ForeignKey(User,on_delete=models.CASCADE)

    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type','object_id')

    date = models.DateTimeField(auto_now=True)

所以我有这个结构models.py。这里是对重要模型的解释:
事件模型具有“业务”字段,该字段链接到特定的业务对象,而该对象还具有“经理”字段。此外,事件模型具有“何时”字段,该字段描述事件发生的日期。
另一方面,Like模型具有可链接到特定Event对象的通用外键字段,还具有“ person”和“
date”字段,这些字段描述谁给了谁以及何时给该事件提供了like。

现在的目标是在用户页面上显示目标用户喜欢的所有事件,以及该用户是该管理员的所有事件。只需使用以下SQL命令即可完成:

SELECT event.*
FROM event
INNER JOIN 
     business
     ON (event.business_id = business.id)
LEFT JOIN
    'like'
    ON (event.id = object_id AND content_type_id = 17)
WHERE ('like'.person_id = 1 OR business.manager_id = 1);

但是现在必须对结果进行排序了,就像在Like中提到的“日期”和在事件模型中提到的“何时”一样。排序行为应如下所示:如果Event对象是从Like对象派生的,则应在该Like对象中按“日期”对它进行排序,在其他情况下,应在Event中按“何时”对它进行排序-
这是事物发生变化的地方。因此,这是最终原始查询的样子:

SELECT event.*
FROM event
INNER JOIN
    business
    ON (event.business_id = business.id AND business.manager_id = 1)
LEFT JOIN
    'like'
    ON (event.id = object_id AND content_type_id = 17 AND person_id = 1)
ORDER BY COALESCE('like'.date,event.'when') DESC;

现在我必须将最后一个查询转换为Django ORM,但是我完全迷失了这一部分。谁能帮我?提前致谢!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。