Django - запрос косвенного присоединения - PullRequest
0 голосов
/ 20 февраля 2012

Как я могу вернуть косвенный объединенный запрос, который дает мне все вопросы в модели вопросов.Предостережение в том, что для каждого вопроса мне нужно иметь доступ к модели UserData.Косвенная связь - это вопрос -> пользователь и пользователь <- данные пользователя (я предпочитаю не менять структуру модели, если это возможно). </p>

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)

Редактировать: я думаю, что эта связь считается "обратной связью".

Ответы [ 2 ]

2 голосов
/ 20 февраля 2012
Question.objects.select_related('user__userdata').all()

получит как объект User, так и объект UserData для каждого вопроса. Обратные отношения не поддерживаются , за исключением в OneToOne таких отношений, как у вас ( Как видно здесь )

1 голос
/ 20 февраля 2012

Рассмотрим select_related () .

От 3 запросов до 2 запросов только с select_related (), до 1 запроса с select_related () с лучшими аргументами.

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'): вы можете видеть, как последний запрос извлекает данные из 3 таблиц, просто набрав 'user__userdata':

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")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...