Home > database >  Django - How to add multiple objects one after another
Django - How to add multiple objects one after another

Time:01-06

I want to make a Quiz app, u will enter the app and u will have 2 buttons:

  1. Create a Quiz
  2. Solve a Quiz

When you press "Create a quiz" you will need to insert your name and press a button that takes you to add a new question in that quiz.I can only add one question, after i press submit it stops.

The problem is that i want to continuously add questions and stop when i added enough. Each question to have a button Add Next Question that automatically saves the question and goes to add the next one and the Finnish Quiz button that stops the proccess of adding questions.I dont know how to add the questions continuously.

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'),

]

CodePudding user response:

Here's Some Very Simple 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)

There are 2 Solutions :-

1. Are you Familiar with Javascript? Add a Button which on click add new form of five inputs for 1 question and four answers. Javascript

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

In the very start, ask creator how many questions he want to be in his Quiz, And then use for loop in template file and provide that number of forms.

CodePudding user response:

# 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})

I did this and it worked, ty for the help! After ive put the get_success_url now everytime i press submit i will get to enter a new question infinitely until i stop.

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