<class> has no foreign key to <class> in Django when trying to inline models

17,219

Solution 1

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.

Solution 2

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.

Solution 3

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

Share:
17,219
user1483801
Author by

user1483801

Currently working at Imaginary Landscape in Chicago, IL as a Python/Django developer. I generally release all my side projects as open source. You can find them at: http://github.com/f4nt/djtracker http://github.com/f4nt/django-yaba I also try to contribute back to open source projects when possible. I've made some (generally small) commits to the following: http://github.com/digi604/django-cms-2.0 http://github.com/imagescape/iscape-djangonews http://github.com/imagescape/iscape-jobboard http://github.com/Poromenos/apache-config http://github.com/thauber/django-schedule

Updated on August 13, 2022

Comments

  • user1483801
    user1483801 almost 2 years

    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?