< class > no tiene una clave externa para < class > en Django cuando se trata de modelos en línea

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

  •  03-07-2019
  •  | 
  •  

Pregunta

Necesito poder crear una aplicación de tipo de prueba con 20 preguntas de opción múltiple extrañas.

Tengo 3 modelos: Quizzes , Questions y Answers .

Quiero que en la interfaz de administración cree un cuestionario, e inserte los elementos de cuestionario y respuesta.

El objetivo es hacer clic en " Agregar prueba " ;, y ser transferido a una página con 20 campos de preguntas, con 4 campos de respuesta por cada uno en su lugar.

Esto es lo que tengo actualmente:

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)

Recibo el siguiente error cuando intento agregar una prueba:

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

¿Esto es factible o estoy tratando de sacar demasiado de la aplicación de administración de Django?

¿Fue útil?

Solución

No puede hacer " anidado " inlines en el administrador de Django (es decir, no puede tener una Prueba con preguntas en línea, con cada pregunta en línea que tenga respuestas en línea). Por lo tanto, tendrá que bajar la vista para simplemente tener preguntas en línea (luego, si navega para ver una sola pregunta, podría tener respuestas en línea).

Por lo tanto, sus modelos están bien, pero su código de administración debería tener este aspecto:

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]

No tiene sentido que AnswerAdmin tenga un AnswerInline, o QuestionAdmin para tener un QuestionInline (a menos que estos sean modelos con una clave externa autorreferencial). Y QuizAdmin no puede tener un AnswerInline, porque Answer no tiene una clave externa para Quiz.

Si Django admitiera inlines anidados, la sintaxis lógica sería que QuestionInline acepte un " inlines " atributo, que se establece en [AnswerInline]. Pero no es así.

También ten en cuenta que " extra = 20 " significa que tendrá 20 formularios de preguntas en blanco al final de cada cuestionario, cada vez que lo cargue (incluso si ya tiene 20 preguntas reales). Tal vez eso es lo que quieres: hace que la página sea larga, pero te facilita agregar muchas preguntas a la vez.

Otros consejos

Vamos a seguir paso a paso.

El error: " La respuesta no tiene FK para la prueba " ;.

Eso es correcto. El modelo de respuesta no tiene FK a prueba. Tiene un FK a la pregunta, pero no prueba.

¿Por qué la Respuesta necesita un FK para hacer una prueba?

El QuizAdmin tiene un AnswerInline y un QuestionInline. Para que un administrador tenga líneas, significa que los modelos en línea (Respuesta y Pregunta) deben tener FK para el administrador principal.

Vamos a comprobar. La pregunta tiene un FK a prueba.

Y. La respuesta no tiene FK a Quiz. Entonces, el administrador de tu prueba exige un FK del que carece tu modelo. Ese es el error.

Correcto: tratando de sacar demasiado de la aplicación de administración :) Los modelos en línea necesitan una clave externa para el modelo principal.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top