Question

I need to be able to create a quiz type application with 20 some odd multiple choice questions.

I have 3 models: Quizzes, Questions, and Answers.

I want in the admin interface to create a quiz, and inline the quiz and answer elements.

The goal is to click "Add Quiz", and be transferred to a page with 20 question fields, with 4 answer fields per each in place.

Here's what I have currently:

class Quiz(models.Model):
    label = models.CharField(blank=true, max_length=50)

class Question(models.Model):
    label = models.CharField(blank=true, max_length=50)
    quiz = models.ForeignKey(Quiz)

class Answer(models.Model):
    label = models.CharField(blank=true, max_length=50)
    question = models.ForeignKey(Question)

class QuestionInline(admin.TabularInline):
    model = Question
    extra = 20

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

class AnswerInline(admin.TabularInline):
    model = Answer
    extra = 4

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

class QuizAdmin(admin.ModelAdmin):
    inlines = [QuestionInline, AnswerInline]

admin.site.register(Question, QuestionAdmin)
admin.site.register(Answer, AnswerAdmin)
admin.site.register(Quiz, QuizAdmin)

I get the following error when I try to add a quiz:

class 'quizzer.quiz.models.Answer'> has no ForeignKey to <class 'quizzer.quiz.models.Quiz'>

Is this doable, or am I trying to pull too much out of the Django Admin app?

Was it helpful?

Solution

You can't do "nested" inlines in the Django admin (i.e. you can't have a Quiz with inline Questions, with each inline Question having inline Answers). So you'll need to lower your sights to just having inline Questions (then if you navigate to view a single Question, it could have inline Answers).

So your models are fine, but your admin code should look like this:

class QuestionInline(admin.TabularInline):
    model = Question
    extra = 20

class AnswerInline(admin.TabularInline):
    model = Answer
    extra = 4

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

class AnswerAdmin(admin.ModelAdmin):
    pass

class QuizAdmin(admin.ModelAdmin):
    inlines = [QuestionInline]

It doesn't make sense for AnswerAdmin to have an AnswerInline, or QuestionAdmin to have a QuestionInline (unless these were models with a self-referential foreign key). And QuizAdmin can't have an AnswerInline, because Answer has no foreign key to Quiz.

If Django did support nested inlines, the logical syntax would be for QuestionInline to accept an "inlines" attribute, which you'd set to [AnswerInline]. But it doesn't.

Also note that "extra = 20" means you'll have 20 blank Question forms at the bottom of every Quiz, every time you load it up (even if it already has 20 actual Questions). Maybe that's what you want - makes for a long page, but makes it easy to add lots of questions at once.

OTHER TIPS

Let's follow through step by step.

The error: "Answer has no FK to Quiz".

That's correct. The Answer model has no FK to Quiz. It has an FK to Question, but not Quiz.

Why does Answer need an FK to quiz?

The QuizAdmin has an AnswerInline and a QuestionInline. For an admin to have inlines, it means the inlined models (Answer and Question) must have FK's to the parent admin.

Let's check. Question has an FK to Quiz.

And. Answer has no FK to Quiz. So your Quiz admin demands an FK that your model lacks. That's the error.

Correct: trying to pull too much out of admin app :) Inline models need a foreign key to the parent model.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top