Django形式。保存数据但在提交前不进行验证

时间:2017-09-08 14:26:30

标签: django django-forms

我是Django的新手并且一直在阅读很多内容,所以这可能是一个菜鸟问题。

我们的应用程序涉及用户在此过程中填写的许多表单。一个用户可能填写预算页面,另一个用户可能填写项目描述页面。在此过程中,他们输入的任何数据 都将被保存但未经过验证。

在评论页面上,只显示数据,没有输入框/表格。底部是提交按钮。当用户提交应用程序时,我希望在应用程序的所有部分/页面/表单上执行验证。如果存在验证错误,则无法提交申请。

我的模型字段大多标记为空白= True或null = True,具体取决于字段类型。某些字段是必需的,但大多数我留空或为空以允许用户沿途输入数据。

非常感谢任何关于最佳实践的建议或不重复自己。

2 个答案:

答案 0 :(得分:0)

django中有一个名为form wizard的应用程序。使用它,您可以分割表单提交过程以执行多个步骤。

答案 1 :(得分:0)

经过大量的学习,玩耍和阅读,我认为我已经掌握了一些东西,并将在这里分享。我不知道这是否对,但是对我来说这是进步。

因此首先是模型。根据字段类型,所有内容都必须接受空白或null。这将允许最终用户在获取数据时输入数据:

class exampleModel(models.Model):
    field_1 = models.CharField(blank=True, max_length=25)
    field_2 = models.CharField(blank=True, max_length=50)
    .........

然后我们创建模型表格:

from your.models import exampleModel
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Row, Column

class exampleForm(ModelForm):
    class Meta:
        model = exampleModel
        fields = ('field_1','field_2')

    def __init__(self, *args, **kwargs):

        # DID WE GET A VALIDATE ARGUMENT?
        self.validate = kwargs.pop('validate', False)
        super(ExampleForm, self).__init__(*args, **kwargs)

        # SEE IF WE HAVE TO VALIDATE
        for field in self.fields:
            if self.validate:
                self.fields[field].required = True
            else:
                self.fields[field].required = False

        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.layout = Layout(
            Row(
                Column('field_1', css_class='col-lg-4 col-md-4'),
                Column('field_2', css_class='col-lg-4 col-md-4')
            )
        )

    def clean(self):
        cleaned_data = super(ExampleForm, self).clean()

        field_1 = cleaned_data.get('field1')
        field_2 = cleaned_data.get('field2')

        if self.validate and field_2 != field_2:
            self.add_error('field_1', 'Field 1 does not match field2')

        return cleaned_data

这是重要的部分。我已经学到了很多有关表单和绑定的知识。正如我提到的,我需要用户能够填写表格,直到最后才验证数据。这是对我有帮助的解决方案。我找不到将表单绑定到模型数据的方法,所以我在我的库中创建了一个名为bind_queryset_to_form的函数,如下所示:

def bind_queryset_to_form(qs, form):
    form_data = {}
    my_form = form()
    for field in my_form.fields:
        form_data[field] = getattr(qs, field, None)
    my_form = form(data=form_data, validate=True)
    return my_form

视图:

from your.models import exampleModel
from your.form import exampleForm
from your.lib.bind_queryset_to_form import bind_queryset_to_form

from django.shortcuts import render, get_object_or_404

def your_view(request, pk):
    query_set = get_object_or_404(exampleModel, id=pk)
    context = dict()
    context['query_set'] = query_set

    # SAVE THE FORM (POST)
    if request.method == 'POST':
        form = exampleForm(request.POST, instance=query_set)
        form.save()
        context['form'] = form

    # GET THE DATA.
    if request.method == 'GET':
       if request.session.get('validate_data'):
           # BIND AND VALIDATE
           context['form'] = bind_queryset_to_form(query_set, exampleForm)
       else:
           # NO BIND, NO VALIDATE
           context['form'] = exampleForm(instance=query_set)

    return render(request, 'dir/your.html', context)

模板:

{% load crispy_forms_tags %}
<div id="div_some_tab">
    <form id="form_some_tab" action="{% url 'xx:xx' query_set.id %}" method="post">
        {% crispy form form.helper %}
    </form>
</div>

以上所有允许什么?

我有很多数据输入的视图。用户可以访问每个视图并根据需要添加数据。在查看页面上,我设置标志/会话“ validate_data”。这将导致应用程序开始验证所有字段。任何错误都将显示在查看页面上。当用户去纠正给定视图的错误时,称为 bind_queryset_to_form(query_set,exampleForm)的操作就是将表单与查询集中的数据绑定在一起并突出显示任何错误。

我删除了很多例外情况和权限,以使其尽可能保持透明(山羊会讨厌)。希望这个想法可以对其他人有所帮助,或者对其他人有所改善。