2009-03-04 26 views
6

Tôi cần có khả năng tạo ứng dụng loại bài kiểm tra với 20 câu hỏi trắc nghiệm lẻ.<class> không có khoá ngoại nào để <class> ở Django khi cố gắng mô hình nội tuyến

Tôi có 3 kiểu: Quizzes, QuestionsAnswers.

Tôi muốn trong giao diện quản trị để tạo một bài kiểm tra và điền vào phần tử câu hỏi và trả lời.

Mục tiêu là nhấp vào "Thêm câu hỏi" và được chuyển đến một trang có 20 trường câu hỏi, với 4 trường câu trả lời cho mỗi trường tại chỗ.

Dưới đây là những gì tôi hiện có:

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) 

tôi nhận được lỗi sau khi tôi cố gắng thêm một bài kiểm tra:

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

phải là doable này, hoặc tôi đang cố gắng để kéo quá nhiều ra của ứng dụng Admin Django?

Trả lời

14

Bạn không thể làm "nested" inlines trong quản trị viên Django (nghĩa là bạn không thể có câu hỏi có câu hỏi nội tuyến, với mỗi câu hỏi nội tuyến có câu trả lời nội tuyến). Vì vậy, bạn sẽ cần phải giảm tầm nhìn của bạn để chỉ có câu hỏi nội tuyến (sau đó nếu bạn điều hướng để xem một câu hỏi duy nhất, nó có thể có câu trả lời nội tuyến).

Vì vậy, mô hình của bạn là tốt, nhưng mã admin của bạn sẽ giống như thế này:

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] 

Nó không có ý nghĩa cho AnswerAdmin để có một AnswerInline, hoặc QuestionAdmin để có một QuestionInline (trừ khi đây là những mô hình với khóa ngoại tự tham chiếu). Và QuizAdmin không thể có một AnswerInline, bởi vì Answer không có khóa ngoại để Quiz.

Nếu Django đã hỗ trợ lồng nhau nội tuyến, cú pháp hợp lý sẽ là cho QuestionInline chấp nhận thuộc tính "nội tuyến" mà bạn đã đặt thành [AnswerInline]. Nhưng nó không. Cũng lưu ý rằng "extra = 20" có nghĩa là bạn sẽ có 20 câu hỏi trống ở cuối mỗi Quiz, mỗi khi bạn tải nó lên (ngay cả khi nó đã có 20 câu hỏi thực tế).Có thể đó là những gì bạn muốn - tạo ra một trang dài, nhưng giúp bạn dễ dàng thêm nhiều câu hỏi cùng một lúc.

2

Đúng: cố gắng kéo quá nhiều ứng dụng quản trị :) Mô hình nội tuyến cần có khóa ngoại vào mô hình gốc.

3

Hãy làm theo từng bước.

Lỗi: "Trả lời không có FK để trả lời".

Chính xác. Mô hình Trả lời không có FK để Quiz. Nó có một FK to Question, nhưng không phải Quiz.

Tại sao câu trả lời cần FK để trả lời?

QuizAdmin có AnswerInline và QuestionInline. Đối với một quản trị viên để có inlines, nó có nghĩa là các mô hình nội tuyến (Trả lời và câu hỏi) phải có FK của quản trị viên phụ huynh.

Hãy kiểm tra. Câu hỏi có một FK để Quiz.

Và. Trả lời không có FK để Quiz. Vì vậy, quản trị viên Quiz yêu cầu một FK mà mô hình của bạn thiếu. Đó là lỗi.

Các vấn đề liên quan