<class> не имеет внешнего ключа к <class> в Django при попытке встроить модели

StackOverflow https://stackoverflow.com/questions/609556

  •  03-07-2019
  •  | 
  •  

Вопрос

Мне нужно иметь возможность создать приложение типа викторины с 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?

Это было полезно?

Решение

Вы не можете " вложенные " inline в админке 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 фактических Вопросов). Может быть, это то, что вы хотите - создает длинную страницу, но позволяет легко добавлять множество вопросов одновременно.

Другие советы

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

Ошибка:"Ответ не имеет отношения к Тестированию".

Это верно.Модель ответов не имеет никакого отношения к Тестированию.В нем есть Возможность задавать Вопросы, но не Викторина.

Почему для ответа на тест нужен FK?

У администратора викторины есть строка ответа и строка вопроса.Чтобы у администратора были встроенные строки, это означает, что встроенные модели (Answer и Question) должны иметь FK для родительского администратора.

Давайте проверим.Вопрос имеет отношение к Викторине.

И.Ответ не имеет отношения к Тестированию.Итак, ваш администратор викторины требует FK, которого нет в вашей модели.В этом и заключается ошибка.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top