Django, как сделать обратную ссылку внешнего ключа - PullRequest
0 голосов
/ 11 марта 2012

Я строю систему онлайн-тестирования, в настоящее время у меня есть 2 таблицы:

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, чтобы сузить набор запросов и передать соответствующий ответ в шаблон, но это не сработало, потому что я не знаю, что вставить в Answer.objects.filter(ID = ???).Любая идея?Также попытался использовать форму.

Обновление: я сделал это: используя

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)

Работает, но требует, чтобы идентификатор ответа был таким же, как ссылка на идентификатор вопроса, есть ли лучший способ?

Ответы [ 4 ]

1 голос
/ 12 марта 2012

Вместо того, чтобы изменить представление, вы решили использовать встроенную функциональность администратора 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)

Таким образом, вам действительно нужен только один класс администратора (для вашей модели Вопроса), и ответы всегда на месте. Просто мысль, это то, что я интенсивно использую в своих проектах.

0 голосов
/ 20 марта 2013
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)

Это работает, но требует, чтобы идентификатор ответа совпадал со ссылкой на идентификатор вопроса, есть ли лучший способ?

0 голосов
/ 12 марта 2012

Один из возможных подходов - использовать 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)
0 голосов
/ 11 марта 2012

Я думаю, что вы ищете это . Вы можете фильтровать по другим ключам, кроме ID. Ваш код, вероятно, будет что-то вроде Answer.objects.filter(question = myquestion)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...