Django - Как добавить несколько объектов один за другим
Я хочу сделать приложение викторины, вы войдете в приложение и у вас будет 2 кнопки:
- Create a Quiz
- 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})
Я сделал это и все получилось, спасибо за помощь!