Django - Как добавить несколько объектов один за другим

Я хочу сделать приложение викторины, вы войдете в приложение и у вас будет 2 кнопки:

  1. Create a Quiz
  2. Solve a Quiz

Когда вы нажимаете "Создать викторину", вам нужно вставить свое имя и нажать кнопку, которая позволяет добавить новый вопрос в викторину. Я могу добавить только один вопрос, после того как я нажимаю отправить, он останавливается.

Проблема заключается в том, что я хочу постоянно добавлять вопросы и останавливаться, когда я добавил достаточно. Каждый вопрос должен иметь кнопку Add Next Question, которая автоматически сохраняет вопрос и переходит к добавлению следующего и кнопку Finnish Quiz, которая останавливает процесс добавления вопросов.Я не знаю, как добавлять вопросы непрерывно.

Views.py

from django.shortcuts import render
from django.urls import reverse_lazy
from django.views.generic import CreateView, TemplateView, DetailView

from quiz.forms import QuestionForm, QuizIdentifierForm
from quiz.models import Question, QuizIdentifier


# HOMEPAGE
class HomeTemplateView(TemplateView):
    template_name = "quiz/homepage.html"


# QUIZ
class QuizCreateView(CreateView):
    template_name = 'quiz/add_quiz.html'
    model = QuizIdentifier
    form_class = QuizIdentifierForm

    def get_success_url(self):
        return reverse_lazy('add-question', kwargs={'quiz_id': self.object.pk})


class QuizDetailView(DetailView):
    template_name = 'quiz/detail_quiz.html'
    model = QuizIdentifier


# QUESTION
class QuestionCreateView(CreateView):
    template_name = 'quiz/add_question.html'
    model = Question
    success_url = reverse_lazy('home')
    form_class = QuestionForm

    def form_valid(self, form):
        res = super().form_valid(form)
        self.object.quiz_id = self.kwargs['quiz_id']
        self.object.save()
        return res


def get_questions_per_quiz(request, pk):
    questions_per_quiz = Question.objects.filter(quiz_id=pk)
    context = {'all_questions': questions_per_quiz, 'pk': pk}
    return render(request, 'quiz/quiz_questions.html', context)

Models.py

import uuid

from django.db import models
from django.db.models import ForeignKey


class QuizIdentifier(models.Model):
    creator_name = models.CharField(max_length=100)
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    def __str__(self):
        return self.creator_name


class Question(models.Model):
    question = models.CharField(max_length=400, null=True)
    op1 = models.CharField(max_length=400, null=True)
    op2 = models.CharField(max_length=400, null=True)
    op3 = models.CharField(max_length=400, null=True)
    op4 = models.CharField(max_length=400, null=True)
    answer = models.CharField(max_length=400, null=True)
    quiz = ForeignKey(QuizIdentifier, on_delete=models.CASCADE, null='True')

    def __str__(self):
        return self.question

Forms.py

from django.forms import ModelForm, TextInput, Select
from .models import *
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User


class CreateUserForm(UserCreationForm):
    class Meta:
        model = User
        fields = ['username', 'password']


class QuestionForm(ModelForm):
    class Meta:
        model = Question
        fields = ['question', 'op1', 'op2', 'op3', 'op4', 'answer']
        widgets = {
            'question': TextInput(attrs={'placeholder': 'Enter the question!'}),
            'op1': TextInput(attrs={'placeholder': 'Enter the first option!'}),
            'op2': TextInput(attrs={'placeholder': 'Enter the second option!'}),
            'op3': TextInput(attrs={'placeholder': 'Enter the third option!'}),
            'op4': TextInput(attrs={'placeholder': 'Enter the fourth option!'}),
            'answer': TextInput(attrs={'placeholder': 'Enter the answer!'}),
            'quiz': Select(),
        }


class QuizIdentifierForm(ModelForm):
    class Meta:
        model = QuizIdentifier
        fields = ['creator_name']
        widgets = {
            'creator_name': TextInput(attrs={'placeholder': 'Enter your name!'})
        }

Urls.py

from django.urls import path
from quiz import views


urlpatterns = [
    path('', views.HomeTemplateView.as_view(), name='home'),
    path('add-question/<quiz_id>', views.QuestionCreateView.as_view(), name="add-question"),
    path('quiz/<str:pk>', views.get_questions_per_quiz, name='quiz'),
    path('create-a-quiz/', views.QuizCreateView.as_view(), name="create-a-quiz"),
    path('quiz-details/<str:pk>', views.QuizDetailView.as_view(), name='quiz-details'),

]

Измените success_url в вашем QuestionCreateView на тот же url.

class QuestionCreateView(CreateView):
    template_name = 'quiz/add_question.html'
    model = Question
    success_url = reverse_lazy('add_question')
    form_class = QuestionForm

В вашем шаблоне, вероятно, также следует разместить кнопку, которая перенаправляет вас на просмотр подробностей викторины.

<a href="{% url 'quiz-details` quiz.pk %}>Go back to quiz</a>

Вот несколько очень простых Models.py

class Quiz(models.Model):
    questions = models.ManyToManyField("Question", blank=True)

class Question(models.Model):
    question = models.TextField()
    answers = models.ManyToManyField("Answer", blank=True)

class Answer(models.Model):
    answer = models.TextField()
    is_correct = models.BooleanField(default=False)

Есть 2 решения :-

1. Знакомы ли вы с Javascript? Добавьте кнопку, которая при нажатии добавляет новую форму из пяти входов для 1 вопроса и четырех ответов. Javascript

// add new question and answer form
addQuestion = () => {
    var container = document.querySelector("#yourDivIdOfQuestionsContainer");
    container.appendChild("yourFormHere");
}

В самом начале спросите создателя, сколько вопросов он хочет видеть в своей викторине, А затем используйте цикл for в файле шаблона и предоставьте это количество форм.

# QUESTION
class QuestionCreateView(CreateView):
    template_name = 'quiz/add_question.html'
    model = Question
    form_class = QuestionForm

    def get_success_url(self):
        question_quiz_id = self.kwargs['quiz_id']
        return reverse_lazy('add-question', kwargs={'quiz_id': question_quiz_id})

Я сделал это и все получилось, спасибо за помощь!

Вернуться на верх