Djnago通用视图数据验证

时间:2019-11-23 17:45:11

标签: python django

我有一个 Item 模型,其中有 Row 模型中的前键。

models.py

from django.db import models
from django.urls import reverse
from django.utils import timezone


class Item(models.Model):
    item_name = models.CharField(max_length=100, unique=True, validators=[validate_test])
    number_of_questions = models.IntegerField(default=0)
    number_of_read_questions = models.IntegerField(default=0)

    def get_absolute_url(self):
        return reverse('uni_checker:main_editor')


class Row(models.Model):
    item = models.ForeignKey(Item, on_delete=models.CASCADE)
    row_name = models.CharField(max_length=100, validators=[validate_test])
    is_completed = models.BooleanField(default=False)
    deadline = models.DateField(default=timezone.now())

我正在寻找可以在一页上创建类似内容的解决方案:

  

Item1_name:

     
      
  • Row1_name;
  •   
  • Row2_name;
  •   
  • Row3_name;
  •   
     

Item2_name:

     
      
  • Row4_name;
  •   
  • Row5_name;
  •   
  • Row6_name;
  •   
     

screenshot

问题

对于创建对象,我将 CreateView form_class = Item 一起使用,并将上下文变量 formset Row 表单一起使用。

问题是,我不仅不知道如何验证表单中的数据,还不知道如何验证表单集中的数据。 如果我在 row_name 字段中输入了无效数据,它只会保存 Item 对象,而不会保存 Row 对象或显示错误。

我知道视图类或表单创建中有问题,但是我找不到正确的方法。

代码

views.py

from django.views.generic import ListView
from .models import Item
from django.urls import reverse
from .forms import ExampleFormSetHelper, CreateRowFormSet, ItemForm
from crispy_forms.layout import Submit


class ItemCreateView(CreateView):
    model = Item
    template_name = "uni_checker/item_create.html"
    form_class = ItemForm

    def get_context_data(self, **kwargs):
        data = super(ItemCreateView, self).get_context_data(**kwargs)
        helper = ExampleFormSetHelper()
        helper.add_input(Submit("submit", "Save"))
        data["helper"] = helper
        if self.request.POST:
            data['formset'] = CreateRowFormSet(self.request.POST)
        else:
            data['formset'] = CreateRowFormSet()
        return data

    def form_valid(self, form):
        context = self.get_context_data()
        formset = context['formset']
        if formset.is_valid() and form.is_valid():
            form.save()
            for temp_form in formset:
                instance = temp_form.save(commit=False)
                instance.item = form.save()
                instance.save()
        return super(ItemCreateView, self).form_valid(form)

    def get_success_url(self):
        return reverse('uni_checker:main_editor')

forms.py

from django import forms
from django.forms.formsets import BaseFormSet

from .models import Item, Row
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Field
from django.forms import inlineformset_factory


class ExampleFormSetHelper(FormHelper):
    def __init__(self, *args, **kwargs):
        super(ExampleFormSetHelper, self).__init__(*args, **kwargs)
        self.form_method = 'post'
        self.layout = Layout(
        Field('row_name', required=True),
        Field('deadline', required=True),
        )
        self.render_required_fields = True
        self.form_tag = False


class ItemForm(forms.ModelForm):
    class Meta:
        model = Item
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        super(ItemForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.helper.form_method = 'post'
        self.helper.render_required_fields = True
        self.helper.form_tag = False


CreateRowFormSet = inlineformset_factory(Item, Row, fields='__all__', extra=3)
UpdateRowFormSet = inlineformset_factory(Item, Row, fields='__all__', extra=0)

template.html


{% extends "uni_checker/base.html" %}
{% block content %}


{% load crispy_forms_tags %}

<form class="uniForm" method="post">
{% csrf_token %}


{% crispy form %}
{% crispy formset helper %}
</form>


{% endblock %}

0 个答案:

没有答案