我只想用Python Django语法编写以下SQL查询。我做了很多研究,但没有得到想要的结果。请你帮助我好吗。

    SELECT * FROM thread
    LEFT JOIN user
    ON (thread.user1_id = user.id OR thread.user2_id = user.id)
    WHERE user.id = 9


我的模特:

 class Thread(models.Model):
        last_message = models.TextField(max_length=100)
        user1_id = models.IntegerField()
        user2_id = models.IntegerField()

最佳答案

不使用某些原始SQL,就无法使用Django ORM创建确切的查询。问题是联接条件中的OR。

但是,由于未从用户表中选择任何行,因此可以创建具有相同结果的不同查询。

首先使用ForeignKeys定义模型。

from django.db import models
from django.contrib.auth.models import User

class Thread(models.Model):
    last_message = models.TextField(max_length=100)
    user1 = models.ForeignKey(User)
    user2 = models.ForeignKey(User)

    class Meta:
        db_table = 'thread'  # otherwise it will be: appname_thread


然后,您可以执行查询。

from django.db.models import Q

threads = Thread.objects.filter(Q(user1__id=9) | Q(user2__id=9))


产生的SQL将如下所示:

SELECT * FROM thread
LEFT JOIN user AS user1
ON (thread.user1_id = user1.id)
LEFT JOIN user AS user2
ON (thread.user2_id = user2.id)
WHERE (user1.id = 9 OR user2.id = 9)




您可以通过完全避免联接来改善这一点。

# note the single underscore!
threads = Thread.objects.filter(Q(user1_id=9) | Q(user2_id=9))


生成以下SQL。

SELECT * FROM thread
WHERE (user1_id = 9 OR user2_id = 9)




如果您还需要在同一查询中获取用户实例(在这种情况下,您确实需要连接),则有两个选择。


使用包含联接的第一个查询,然后根据Python中的id选择正确的用户。

for thread in threads:
    if thread.user1.id == 9:
        user = thread.user1
    else:
        user = thread.user2

或使用原始SQL来获取所需的确切查询。在这种情况下,您可以在定义外键时使用没有外键的模型。

threads = Thread.objects.raw('''
           SELECT *, user.id AS user_id, user.name as user_name FROM thread
           LEFT JOIN user
           ON (thread.user1_id = user.id OR thread.user2_id = user.id)
           WHERE user.id = 9''')
for thread in threads:
    # threads use the ORM
    thread.id
    # user fields are extra attributes
    thread.user_id
    thread.user_name

关于python - python django中具有OR条件的LEFT JOIN,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36936944/

10-13 07:48
查看更多