在Django项目中,我有一个视图(云),输入:CreateView。此视图具有inlineformset_factory。有用。但是,如果我提交带有错误的表单(请查看" messages.error"下面),页面将重定向到project.get_absolute_url()。问题是:表单内容回空。我知道那是因为HttpResponseRedirect。
如何在不破坏表格的情况下更改此内容?
views.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
<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>
答案 0 :(得分:24)
作为一般规则,模型验证应该进入模型字段验证器或模型的clean
方法。表单验证应采用表单的clean
或clean_<field>
方法。
如果您需要在视图的form_valid
中验证内容,则可以使用form.add_error
然后重新定向(或返回super(cloud, self).form_valid(form)
,无论如何重定向),您可以返回{ {1}}。
检查: https://docs.djangoproject.com/en/1.9/ref/forms/api/#django.forms.Form.add_error