如何在CreateView的form_valid方法内引发错误 [英] How to raise a error inside form_valid method of a CreateView

查看:74
本文介绍了如何在CreateView的form_valid方法内引发错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Django项目中,我有一个视图(云),键入:CreateView。此视图具有inlineformset_factory。有用。但是,如果我提交的表单有错误(请参见下面的 messages.error),则页面将重定向到project.get_absolute_url()。问题是:表单内容返回空。我知道那是因为HttpResponseRedirect。

In a Django project, I have a view (cloud), type: CreateView. This view has a inlineformset_factory. It works. But, if i submit the form with a error (look at "messages.error" below), the page is redirected to project.get_absolute_url(). The problem is: the form content back empty. I know thats because the HttpResponseRedirect.

如何更改此样式而不破坏表格?

How can I change this without to break the form?

视图。 py

class cloud(CreateView):
    template_name = 'base/cloud.html'
    form_class = UserForm

    def get_context_data(self, **kwargs):
        context = super(cloud, self).get_context_data(**kwargs)
        project = get_object_or_404(Project, slug=self.kwargs['slug'])
        context['project'] = project
        if self.request.POST:
            context['formset'] = IdeaFormset(self.request.POST or None)
        else:
            context['formset'] = IdeaFormset()
        return context

    def form_valid(self, form, **kwargs):
        project = get_object_or_404(Project, slug=self.kwargs['slug'])
        context = self.get_context_data()
        formset = context['formset']

        if formset.is_valid():
            self.object = form.save()
            formset.instance = self.object #IdeaFormFormSet

            nouns = project.nouns().values_list('content', flat=True)
            verbs = project.verbs().values_list('content', flat=True)
            error = False
            for form in formset.forms: #For each Idea
                form.instance.project = project
                if form.instance.sentence:
                    sentence = form.instance.sentence
                    validate_noun = [word for word in sentence.lower().split() if word in nouns]
                    validate_verbs = [word for word in sentence.lower().split() if word in verbs]

                    if (len(validate_noun) < 1):
                        error = True
                        messages.error(self.request, u'No noun was inserted into the sentence.', 'danger')

                    if (len(validate_verbs) < 1):
                        error = True
                        messages.error(self.request, u'No verb was inserted into the sentence.', 'danger')

            if not error:
                formset.save()
                messages.success(self.request, u'Success!')
            return HttpResponseRedirect( project.get_absolute_url() )

        else:
            return self.render_to_response(self.get_context_data(form=form))

cloud.html

cloud.html

        <form role="form" method="post">
            {% csrf_token %}
            <legend>Ideas</legend>
            <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
            {% for idea_form in formset %}
                {# Include the hidden fields #}
                {% for hidden in idea_form.hidden_fields %}
                    {{ hidden }}
                {% endfor %}
                <div class="panel panel-default">
                    <div class="panel-heading" role="tab" id="heading_{{ forloop.counter }}">
                    <h4 class="panel-title">
                        <a {% if not forloop.first %} class="collapsed" {% endif %}
                            data-toggle="collapse" data-parent="#accordion" href="#collapse_{{ forloop.counter }}" aria-expanded="{{ forloop.first }}" aria-controls="collapse_{{ forloop.counter }}">
                            Idea #{{ forloop.counter }}
                        </a>
                    </h4>
                    </div>

                    <div id="collapse_{{ forloop.counter }}" class="panel-collapse collapse {% if forloop.first %} in {% endif %}" role="tabpanel" aria-labelledby="heading_{{ forloop.counter }}">
                        <div class="panel-body form-group" id="idea_{{ forloop.counter }}">
                            <div class="container-fluid">
                            {% for field in idea_form.visible_fields %}
                                <div class="row">
                                    {{ field.errors }}
                                    {{ field.label_tag }} {{ field }}
                                    <span class="help-block">{{ field.help_text }}</span>
                                </div>
                            {% endfor %}
                            </div> <!--container-fluid-->
                        </div>
                    </div>
                </div>
            {% endfor %}
            </div>

            <legend>User</legend>

            {% for field in form %}
            <div class="form-group has-error">
                {{ field.label_tag }} {{ field }}
                {% if field.help_text %}
                    <p class="help-inline"><small>{{ field.help_text }}</small></p>
                {% endif %}
                <div class="help-block with-errors">
                    <span class="help-block">
                        {% for error in  field.errors %}{{ error }}{% endfor %}
                    </span>
                </div>
            </div>
            {% endfor %}
            {{ formset.management_form }}

            <div class="form-actions">
                <button type="submit" class="btn btn-primary">Send!</button>
            </div>
        </form>


推荐答案

通常,模型验证应纳入模型字段验证器或模型的 clean 方法。表单验证应进入表单的 clean clean_< field> 方法。

As a general rule, model validation should go into model fields validators or model's clean method. Form validation should go into form's clean or clean_<field> methods.

如果需要验证视图的 form_valid 中的内容,可以使用 form.add_error ,然后,而不是重定向(或返回 super(cloud,self).form_valid(form),无论如何都会进行重定向),您可以返回 super(cloud, self).form_invalid(form)

If you need to validate things in your view's form_valid, you can use form.add_error and then, instead of redirecting (or returning super(cloud, self).form_valid(form), which redirects anyways), you could return super(cloud, self).form_invalid(form).

检查:
https://docs.djangoproject.com/en/1.9/ref/forms/api/#django.forms .Form.add_error

这篇关于如何在CreateView的form_valid方法内引发错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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