无法使用Django表单集保存数据 [英] unable to save data using django formsets

查看:70
本文介绍了无法使用Django表单集保存数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以表格形式输入的数据未保存在数据库中,并且未显示任何错误。
Iam试图使用ExamModelForm和QuestionFormset创建至少一个问题的考试。
在create_exam_with_questions.html中输入考试详细信息和问题后,创建按钮未将数据保存到数据库中

The data entered in the form is not saving in the database and it is not showing any errors. Iam trying to create an exam with atleast one question, using ExamModelForm and QuestionFormset. After entering exam details and questions in create_exam_with_questions.html, the create button is not saving the data into the database

views.py

from django.shortcuts import render
from django.shortcuts import redirect
from django.http import HttpResponseRedirect, HttpResponse

from .forms import ExamModelForm, ExamFormset, QuestionFormset
from .models import Question

def create_exam_with_questions(request):
    template_name = 'school/create_exam_with_questions.html'
    if request.method == 'GET':
        examform = ExamModelForm(request.GET or None)
        formset = QuestionFormset(queryset=Question.objects.none())
    elif request.method == 'POST':
        examform = ExamModelForm(request.POST)
        formset = QuestionFormset(request.POST)
        if examform.is_valid() and formset.is_valid():
            # first save this exam, as its reference will be used in `Question`
            exam = examform.save()
            for form in formset:
                # so that `question` instance can be attached.
                question = form.save(commit=False)
                question.exam = exam 
                question.save()
            return redirect("map:map-home")
    return render(request, template_name, {
        'examform': examform,
        'formset': formset,
    })






forms.py


forms.py

from django import forms
from django.forms import (formset_factory, modelformset_factory)
from .models import Exam, Question

class ExamModelForm(forms.ModelForm):
    class Meta:
        model = Exam
        fields = ['name', 'section', 'duration', 'subject', 'start', 'teacher']

QuestionFormset = modelformset_factory(
    Question,
    fields=('question', 'ans', 'op2', 'op3', 'op4', ),
    extra=1,
    widgets={'question': forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Enter Question here'
        }),
    'ans': forms.TextInput(attrs={
        'class': 'form-control',
        'placeholder': 'Enter answer here'
        }),
    'op2': forms.TextInput(attrs={
        'class': 'form-control',
        'placeholder': 'Enter option2 here'
        }),
    'op3': forms.TextInput(attrs={
        'class': 'form-control',
        'placeholder': 'Enter option3 here'
        }),
    'op4': forms.TextInput(attrs={
        'class': 'form-control',
        'placeholder': 'Enter option4 here'
        }),
    }
)






models.py


models.py

class Section(models.Model):
    name = models.CharField(max_length = 20)
    school = models.ForeignKey(School, on_delete = models.CASCADE)

    def __str__(self):
        return self.name

class Subject(models.Model):
    name = models.CharField(max_length = 20)
    section = models.ForeignKey(Section, on_delete = models.CASCADE)

    def __str__(self):
        return self.name


class Exam(models.Model):
    name = models.CharField(max_length = 20)
    section = models.ForeignKey(Section, on_delete = models.CASCADE)
    subject = models.ForeignKey(Subject, on_delete = models.CASCADE)
    duration = models.TimeField()
    start = models.DateTimeField()
    teacher = models.CharField(max_length = 20)

    def __str__(self):
        return self.name


class Question(models.Model):
    question = models.TextField(max_length = 20)
    ans = models.CharField(max_length = 20)
    op2 = models.CharField(max_length = 20)
    op3 = models.CharField(max_length = 20)
    op4 = models.CharField(max_length = 20)
    exam = models.ForeignKey(Exam, on_delete = models.CASCADE)

    def __str__(self):
        return self.question






create_exam_with_questions.html


create_exam_with_questions.html

{% extends "school/base.html" %}

{% block container %}
{% if heading %}
<h3>{{heading}}</h3>
{% endif %}
<form class="form-horizontal" method="POST" action="">
    {% csrf_token %}
<div class="row spacer">
<div class="col-2">
    <label>{{examform.name.label}}</label>
</div>
<div class="col-4">
    <div class="input-group">
        {{examform.name}}
    </div>
</div>
</div>
<div class="row spacer">
<div class="col-2">
    <label>{{examform.subject.label}}</label>
</div>
<div class="col-4">
    <div class="input-group">
        {{examform.subject}}
    </div>
</div>
</div>
<div class="row spacer">
<div class="col-2">
    <label>{{examform.duration.label}}</label>
</div>
<div class="col-4">
    <div class="input-group">
        {{examform.duration}}
    </div>
</div>
</div>
<div class="row spacer">
<div class="col-2">
    <label>{{examform.teacher.label}}</label>
</div>
<div class="col-4">
    <div class="input-group">
        {{examform.teacher}}
    </div>
</div>
</div>
<div class="row spacer">
<div class="col-2">
    <label>{{examform.start.label}}</label>
</div>
<div class="col-4">
    <div class="input-group">
        {{examform.start}}
    </div>
</div>
</div>
<div class="row spacer">
<div class="col-2">
    <label>{{examform.section.label}}</label>
</div>
<div class="col-4">
    <div class="input-group">
        {{examform.section}}
    </div>
</div>
</div>
{{ formset.management_form }}
{% for form in formset %}
<div class="row form-row spacer">
    <div class="col-2">
        <label>{{form.question.label}}</label>
    </div>
    <div class="col-4">
        <div class="input-group">
            {{form.question}}
        </div>
        <div class="input-group">
            {{form.ans}}
        </div>
        <div class="input-group">
            {{form.op2}}
        </div>
        <div class="input-group">
            {{form.op3}}
        </div>
        <div class="input-group">
            {{form.op4}}
        </div>
    </div>
    <div class="input-group-append">
                <button class="btn btn-success add-form-row">+</button>
    </div>
</div>
{% endfor %}
<div class="row spacer">
    <div class="col-4 offset-2">
        <button type="submit" class="btn btn-block btn-primary">Create</button>
    </div>
</div>
</form>
{% endblock %}

{% block custom_js %}
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script type="text/javascript">
function updateElementIndex(el, prefix, ndx) {
    var id_regex = new RegExp('(' + prefix + '-\\d+)');
    var replacement = prefix + '-' + ndx;
    if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex, replacement));
    if (el.id) el.id = el.id.replace(id_regex, replacement);
    if (el.name) el.name = el.name.replace(id_regex, replacement);
}
function cloneMore(selector, prefix) {
    var newElement = $(selector).clone(true);
    var total = $('#id_' + prefix + '-TOTAL_FORMS').val();
    newElement.find(':input:not([type=button]):not([type=submit]):not([type=reset])').each(function() {
        var name = $(this).attr('name')
        if(name) {
            name = name.replace('-' + (total-1) + '-', '-' + total + '-');
            var id = 'id_' + name;
            $(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
        }
    });
    newElement.find('label').each(function() {
        var forValue = $(this).attr('for');
        if (forValue) {
          forValue = forValue.replace('-' + (total-1) + '-', '-' + total + '-');
          $(this).attr({'for': forValue});
        }
    });
    total++;
    $('#id_' + prefix + '-TOTAL_FORMS').val(total);
    $(selector).after(newElement);
    var conditionRow = $('.form-row:not(:last)');
    conditionRow.find('.btn.add-form-row')
    .removeClass('btn-success').addClass('btn-danger')
    .removeClass('add-form-row').addClass('remove-form-row')
    .html('-');
    return false;
}
function deleteForm(prefix, btn) {
    var total = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
    if (total > 1){
        btn.closest('.form-row').remove();
        var forms = $('.form-row');
        $('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
        for (var i=0, formCount=forms.length; i<formCount; i++) {
            $(forms.get(i)).find(':input').each(function() {
                updateElementIndex(this, prefix, i);
            });
        }
    }
    return false;
}
$(document).on('click', '.add-form-row', function(e){
    e.preventDefault();
    cloneMore('.form-row:last', 'form');
    return false;
});
$(document).on('click', '.remove-form-row', function(e){
    e.preventDefault();
    deleteForm('form', $(this));
    return false;
});

</script>
{% endblock %}


推荐答案

您需要替换行

exam = examform.save()

with

examform.save()

保存问题时,写

for form in formset:
    # so that `question` instance can be attached.
    question = form.save(commit=False)
    question.exam = examform
    question.save()

这篇关于无法使用Django表单集保存数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆