Django Quiz - Admin

We'll keep it relatively simple and use the Django Admin for the quiz management. 

 

from django.contrib import admin
from .models import *

# --------------------
# Quiz
# --------------------
@admin.register(Quiz)
class QuizAdmin(admin.ModelAdmin):
    list_display = ("id", "name", "uuid")


# --------------------
# Question (with Answers inline)
# --------------------
class AnswerInline(admin.TabularInline):
    model = Answer
    extra = 1


@admin.register(Question)
class QuestionAdmin(admin.ModelAdmin):
    list_display = ("id", "text", "quiz")
    list_filter = ("quiz",)
    inlines = [AnswerInline]


# --------------------
# Answer (with Dimension weights inline)
# --------------------
class AnswerDimensionInline(admin.TabularInline):
    model = AnswerDimension
    extra = 1

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "dimension" and request.resolver_match:
            answer_id = request.resolver_match.kwargs.get("object_id")
            if answer_id:
                answer = Answer.objects.get(pk=answer_id)
                kwargs["queryset"] = Dimension.objects.filter(
                    quiz=answer.question.quiz
                )
        return super().formfield_for_foreignkey(db_field, request, **kwargs)


@admin.register(Answer)
class AnswerAdmin(admin.ModelAdmin):
    list_display = (
        "id",
        "text",
        "get_quiz",
        "question",
        "dimensions_weights", 
    )
    list_filter = ("question__quiz",)
    inlines = [AnswerDimensionInline]

    def get_quiz(self, obj):
        return obj.question.quiz
    get_quiz.short_description = "Quiz"

    def dimensions_weights(self, obj):
        relations = obj.answerdimension_set.all()

        if not relations.exists():
            return "-"

        return " | ".join(
            f"{rel.dimension.name}: {rel.weight}"
            for rel in relations
        )

    dimensions_weights.short_description = "Dimensions / Weights"


# --------------------
# Dimension
# --------------------
@admin.register(Dimension)
class DimensionAdmin(admin.ModelAdmin):
    list_display = ("id", "name", "quiz")
    list_filter = ("quiz",)


# --------------------
# Profile (with Rules inline)
# --------------------
class ProfileRuleInline(admin.TabularInline):
    model = ProfileRule
    extra = 1

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "dimension" and request.resolver_match:
            profile_id = request.resolver_match.kwargs.get("object_id")
            if profile_id:
                profile = Profile.objects.get(pk=profile_id)
                kwargs["queryset"] = Dimension.objects.filter(
                    quiz=profile.quiz
                )
        return super().formfield_for_foreignkey(db_field, request, **kwargs)


@admin.register(Profile)
class ProfileAdmin(admin.ModelAdmin):
    list_display = ("id", "name", "quiz", "priority")
    list_filter = ("quiz",)
    ordering = ("priority",)
    inlines = [ProfileRuleInline]

 

 

We are now ready to create a quiz. Take the time you need. Don't rush.
Before you jumpt to the database consider using an excel sheet to organize:

  • all the questions/answers;
  • the dimensions and weights;
  • and all the profiles.