我想要的只是用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()
答案 0 :(得分:1)
在不使用某些原始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获取所需的确切查询。在这种情况下,您可以使用没有定义它们的ForeignKeys的模型。
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