Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 649
f4nt Avatar asked Mar 04 '09 07:03

f4nt


People also ask

Can a model have two foreign keys Django?

Your intermediate model must contain one - and only one - foreign key to the source model (this would be Group in our example), or you must explicitly specify the foreign keys Django should use for the relationship using ManyToManyField.

How does Django foreign key work?

Introduction to Django Foreign Key. A foreign key is a process through which the fields of one table can be used in another table flexibly. So, two different tables can be easily linked by means of the foreign key. This linking of the two tables can be easily achieved by means of foreign key processes.

What is inline in Django?

django-inline-actions adds actions to each row of the ModelAdmin or InlineModelAdmin.


1 Answers

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.

like image 131
Carl Meyer Avatar answered Sep 18 '22 12:09

Carl Meyer