好的,我在理解Django的加入和别名方面有些麻烦。我在模型中定义了四个表:(我删除了不相关的列)
class Field(models.Model):
name = models.CharField(max_length=200, default='')
class Survey(models.Model):
name = models.CharField(max_length=200, default='')
class Question(models.Model):
text = models.CharField(max_length=200, default='')
survey = models.ForeignKey(Survey)
class Answer(models.Model):
question = models.ForeignKey(Question)
field = models.ForeignKey(Field)
现在,我可以编写一个非常简单易懂的sql查询,以获取所需的确切信息。看起来像这样:
SELECT s.id, s.name,
q.id as q_id, q.text,
f.id as f_id, f.name as answer
FROM "App_survey" s
JOIN "App_question" q
ON q.survey_id = s.id
JOIN "App_answer" a
ON a.question_id = q.id
JOIN "App_field" f
ON a.field_id = f.id;
但是我无法终生想出如何使用orm做到这一点。我什至无法连接两个表并从两个表中选择数据,更不用说处理别名了。据我所知:
questions = Question.objects.prefetch_related('survey')
questions_dict = [{'form':x.name, 'id':x.id, 'question':x.text} for x in questions]
这给了我一个'Question'对象,没有属性'name'错误。
注意:这是postgres和python,两者都是我的新手。
更新:这是我使用的最终代码,可以使用:
answers = Answer.objects.annotate(
s_id=F('question__survey__id'),
s_name=F('question__survey__name'),
q_id=F('question__id'),
text=F('question__text'),
f_id=F('field__id'),
answer=F('field__name')
)
surveys_dict = [{
'id': x.s_id,
'name':x.s_name,
'q_id':x.q_id,
'text':x.text,
'f_id':x.f_id,
'answer':x.answer
} for x in answers]
感谢两位答辩人,他们很有启发性。
答案 0 :(得分:2)
当您具有select_related(*fields)
关系时(执行ManyToOne
),应使用SQL JOINS
。
questions = Question.objects.select_related('survey')
questions_dict = [{'form':x.survey.name, 'id':x.id, 'question':x.text} for x in questions]
我认为,这就是您所需要的。
答案 1 :(得分:2)
之所以不起作用,是因为您的Question
没有name
属性。 .prefetch_related
只会自动填充相关模型。
您可以做的是注释 Question
对象,例如:
from django.db.models import F
Question.objects.annotate(
answer_text=F('answer__field__name'),
s_name=F('survey__name')
)
现在 this Question
中的QuerySet
s将有两个额外的字段answer_text
和s_name
,其中{相关name
中的Field
,以及Answer
的名称s_name
。