如何返回间接连接查询,该查询为我提供了问题模型中的所有问题。需要注意的是,对于每个问题,我都需要能够访问UserData模型。间接关系是问题 - >用户和用户< - UserData(如果可能,我不想更改模型结构)。
class Question(models.Model):
description = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
image_url = models.CharField(max_length=200)
user = models.ForeignKey(User)
class Answer(models.Model):
question = models.ForeignKey(Question)
text = models.CharField(max_length=16000)
user = models.ForeignKey(User)
class UserData(models.Model):
user = models.OneToOneField(User)
access_token = models.CharField(max_length=32)
profile_image_url = models.CharField(max_length=200)
编辑:我认为这种关系被认为是“反向关系”。
答案 0 :(得分:2)
Question.objects.select_related('user__userdata').all()
将为每个问题同时获取User
对象和UserData
对象。不支持除{/ 1}}关系中的之外的反向关系(As seen here)
答案 1 :(得分:1)
从3个查询到只有select_related()的2个查询,再到select_related()的1个查询给出更好的参数。
In [17]: [q.user.userdata.access_token for q in Question.objects.all()]
DEBUG (0.000) SELECT "testapp_question"."id", "testapp_question"."description", "testapp_question"."pub_date", "testapp_question"."image_url", "testapp_question"."user_id" FROM "testapp_question"; args=()
DEBUG (0.000) SELECT "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."id" = 1 ; args=(1,)
DEBUG (0.000) SELECT "testapp_userdata"."id", "testapp_userdata"."user_id", "testapp_userdata"."access_token", "testapp_userdata"."profile_image_url" FROM "testapp_userdata" WHERE "testapp_userdata"."user_id" = 1 ; args=(1,)
Out[17]: [u'1']
In [18]: [q.user.userdata.access_token for q in Question.objects.all().select_related()]
DEBUG (0.000) SELECT "testapp_question"."id", "testapp_question"."description", "testapp_question"."pub_date", "testapp_question"."image_url", "testapp_question"."user_id", "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "testapp_question" INNER JOIN "auth_user" ON ("testapp_question"."user_id" = "auth_user"."id"); args=()
DEBUG (0.000) SELECT "testapp_userdata"."id", "testapp_userdata"."user_id", "testapp_userdata"."access_token", "testapp_userdata"."profile_image_url" FROM "testapp_userdata" WHERE "testapp_userdata"."user_id" = 1 ; args=(1,)
Out[18]: [u'1']
In [19]: [q.user.userdata.access_token for q in Question.objects.all().select_related('user__userdata')]
DEBUG (0.000) SELECT "testapp_question"."id", "testapp_question"."description", "testapp_question"."pub_date", "testapp_question"."image_url", "testapp_question"."user_id", "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined", "testapp_userdata"."id", "testapp_userdata"."user_id", "testapp_userdata"."access_token", "testapp_userdata"."profile_image_url" FROM "testapp_question" INNER JOIN "auth_user" ON ("testapp_question"."user_id" = "auth_user"."id") LEFT OUTER JOIN "testapp_userdata" ON ("auth_user"."id" = "testapp_userdata"."user_id"); args=()
Out[19]: [u'1']
请注意,您无需与('user', 'user__userdata')
调用所选的相关内容:您可以看到上一个查询仅使用“user__userdata
”从3个表中提取数据:
SELECT
"testapp_question"."id", "testapp_question"."description" [...]
"auth_user"."id", "auth_user"."username" [...]
"testapp_userdata"."id", "testapp_userdata"."user_id" [...]
FROM
"testapp_question" INNER JOIN
"auth_user" ON ("testapp_question"."user_id" = "auth_user"."id") LEFT OUTER JOIN
"testapp_userdata" ON ("auth_user"."id" = "testapp_userdata"."user_id")