我只想用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/