【发布时间】:2016-03-23 01:05:43
【问题描述】:
在一个 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>
【问题讨论】:
-
我认为您的
return HttpResonseRedirect声明可能会缩进一层以仅涵盖成功的案例。此外,取消缩进return self.render_to_response并删除else语句,看看是否有效。 -
另一件事是,听起来您在调用
form.is_valid后尝试检查表单验证。但是我觉得还是用form.clean方法做比较好。
标签: python django django-views