<class> не имеет внешнего ключа для <class>в Django при попытке встроенных моделей - PullRequest
6 голосов
/ 04 марта 2009

Мне нужно создать приложение типа викторины с 20 нечетными вопросами с несколькими вариантами ответов.

У меня есть 3 модели: Quizzes, Questions и Answers.

Я хочу, чтобы в интерфейсе администратора была создана викторина, а также встроены элементы викторины и ответа.

Цель состоит в том, чтобы нажать «Добавить тест» и перейти на страницу с 20 полями вопросов, по 4 поля для ответов на каждом.

Вот что у меня сейчас:

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)

При попытке добавить тест я получаю следующую ошибку:

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

Это выполнимо, или я пытаюсь извлечь слишком много из приложения Django Admin?

Ответы [ 3 ]

14 голосов
/ 04 марта 2009

Вы не можете сделать «вложенные» строки в администраторе Django (т. Е. У вас не может быть викторины со встроенными вопросами, каждый встроенный вопрос имеет встроенные ответы). Поэтому вам нужно понизить прицел до наличия встроенных Вопросов (тогда, если вы перейдете к просмотру одного Вопроса, у него могут быть встроенные Ответы).

Так что с вашими моделями все в порядке, но ваш код администратора должен выглядеть так:

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]

Для AnswerAdmin не имеет смысла иметь AnswerInline, или QuestionAdmin иметь QuestionInline (если это не были модели с самообращающимся внешним ключом). И QuizAdmin не может иметь AnswerInline, потому что у ответа нет внешнего ключа к Quiz.

Если Django действительно поддерживает вложенные строки, логический синтаксис будет для QuestionInline принимать атрибут «inlines», который вы бы установили на [AnswerInline]. Но это не так.

Также обратите внимание, что «extra = 20» означает, что у вас будет 20 пустых форм Вопросов в нижней части каждого Теста, каждый раз, когда вы загружаете его (даже если у него уже есть 20 фактических Вопросов). Может быть, это то, что вы хотите - создает длинную страницу, но позволяет легко добавлять множество вопросов одновременно.

3 голосов
/ 04 марта 2009

Давайте пройдем шаг за шагом.

Ошибка: «Ответ не имеет FK для викторины».

Это верно. Модель ответа не имеет FK для викторины. У него есть FK на вопрос, но нет викторины.

Почему Ответу нужен FK для викторины?

QuizAdmin имеет AnswerInline и QuestionInline. Чтобы у администратора были встроенные функции, это означает, что встроенные модели (ответ и вопрос) должны иметь FK для родительского администратора.

Давайте проверим. Вопрос имеет FK для викторины.

А. Ответ не имеет FK на викторину. Таким образом, ваш администратор Викторины требует FK, которого нет в вашей модели. Это ошибка.

2 голосов
/ 04 марта 2009

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

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