【问题标题】:Django forms. Save data but do not validate until submissionDjango 表单。保存数据,但在提交之前不验证
【发布时间】:2018-02-17 12:21:03
【问题描述】:

我是 Django 新手,并且已经阅读了大量内容,所以这可能是一个菜鸟问题。

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

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

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

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

【问题讨论】:

    标签: django django-forms


    【解决方案1】:

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

    【讨论】:

    【解决方案2】:

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

    首先是模型。根据字段类型,所有内容都需要接受空白或空值。这将允许最终用户在获得数据时输入数据:

    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) 将表单与查询集中的数据绑定并突出显示任何错误。

    我删掉了很多例外和许可,以尽可能保持透明(山羊会讨厌这样)。希望这个想法可以帮助其他人或其他人可能会改进它。

    【讨论】:

      猜你喜欢
      • 2011-10-22
      • 2016-09-03
      • 1970-01-01
      • 1970-01-01
      • 2012-07-16
      • 2016-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多