Django如何进行反向外键引用

时间:2012-03-11 18:50:51

标签: python django backend

我建立了一个在线测试系统,目前我有两个表:

class Answer(models.Model):
    ID = models.IntegerField(primary_key = True)
    answer = models.TextField()

class Question(models.Model):
    ID = models.IntegerField(primary_key = True)
    .....
    answer = ForeinKey(Answer)

我有ModelAdmin

class AnswerAdmin(admin.ModelAdmin):
    ....

class QuestionAdmin(admin.ModelAdmin):
    ....

我正在制作管理网站。我想要的是,每次用户转到问题时,网站只显示与其相关的相应答案,用户可以编辑答案(弹出AnswerAdmin窗口)。我试图覆盖formfield_for_foreignkey(self, db_field, request, **kwargs)中的change_view(self, request, object_id, extra_context=None)QuestionAdmin以缩小查询集并将相关答案传递给模板,但它没有用,因为我不知道要放在{ {1}}。任何的想法?也尝试使用表格。

更新: 我做了这个:使用

Answer.objects.filter(ID = ???)

覆盖QuestionAdmin中的表单并向模板添加上下文:

class QuestionForm(forms.ModelForm):
class Meta:
    model = Question
def __init__(self, *args, **kwargs):
    super(QuestionForm,self).__init__(*args,**kwargs)
    self.fields['answer'].queryset = Answer.objects.filter(ID =  self.instance.answer.ID)

它有效,但它需要答案ID与问题ID引用相同,有更好的方法吗?

4 个答案:

答案 0 :(得分:1)

您是否考虑过使用管理员的内置inlines功能而不是更改视图?

<强> models.py

class Question(models.Model):
   text = models.TextField()

class Answer(models.Model):
   text = models.TextField()
   question = models.ForeignKey(Question)

<强> admin.py

class AnswerInline(admin.TabularInline):
    model = Answer

class QuestionAdmin(admin.ModelAdmin):
    inlines = [AnswerInline]

admin.site.register(Question, QuestionAdmin)

这样,您实际上只需要一个管理类(针对您的问题模型)并且答案始终存在。只是一个想法,这是我在我的项目中大量使用的东西。

答案 1 :(得分:0)

我认为您正在寻找this。您可以过滤ID以外的其他键。 您的代码可能类似于Answer.objects.filter(question = myquestion)

答案 2 :(得分:0)

一种可能的方法是使用modelchoicefield

这样的事情:

def get_question_admin_form(the_q):
    class QuestionAdminForm(forms.ModelForm):
        answers = forms.ModelChoiceField(label="Answers",
                queryset=Question.objects.filter(pk=the_q.pk).answer_set.all())

        # ... other fields

        class Meta:
            model = Question

    return QuestionAdminForm

class QuestionAdmin(admin.modelAdmin):
    model = Question

    def get_formset(self, request, obj=None, **kwargs):
        if obj is not None:
            self.form = get_question_admin_form(obj)
        return super(QuestionAdmin, self).get_formset(request, obj, **kwargs)

答案 3 :(得分:0)

class QuestionForm(forms.ModelForm):
class Meta:
    model = Question
def __init__(self, *args, **kwargs):
    super(QuestionForm,self).__init__(*args,**kwargs)
    self.fields['answer'].queryset = Answer.objects.filter(ID =  self.instance.answer.ID)

覆盖QuestionAdmin中的表单并向模板添加上下文:

def change_view(self, request, object_id, extra_context=None):
    extra_context = extra_context or {}
    extra_context['ID'] = object_id
    return super(QuestionAdmin, self).change_view(request, object_id,
        extra_context=extra_context)

它有效,但它需要答案ID与问题ID引用相同,有更好的方法吗?