所以我创建了一个动态表单集,允许用户添加或删除任意数量的表单。现在,我正在尝试在表单中的字段(block_name)中进行自定义验证。
似乎它正在工作,因为如果用户输入与某个正则表达式不匹配,则不会保存数据。问题是没有消息显示输入错误。
此外,如果用户输入错误数据并尝试提交页面,则会重定向到自身并删除所有输入数据。如果输入错误并且还显示错误消息,如何使页面保持在同一视图中?
forms.py:
import re
from django import forms
from django.forms.models import modelformset_factory
from inventory.models import Block
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
# Form for block requests
class BlockForm(forms.ModelForm):
block_name = forms.CharField(required=True, validators= [RegexValidator('^s\d{3}rf\d*b\d*e\d+r\d+w\d*[cgls][abcdex][ed][hv][sbaec][a-d] [a-d][0-7][apfg]a', message="Please enter valid block name", code="invalid_name")])
def __init__(self, *args, **kwargs):
super(BlockForm, self).__init__(*args, **kwargs)
self.empty_permitted = False
class Meta:
model = Block
fields = ['block_name', 'block_derivatives', 'block_subsystems', 'owners']
def clean_block_name(self):
print self.cleaned_data
block_name = self.cleaned_data.get('block_name')
if block_name == "a":
print ("block name is a")
raise forms.ValidationError(
('Please enter a block name'))
return block_name
models.py:
import datetime
import re
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
from django.db import models
from django.utils import timezone
class Inventory(models.Model):
class Meta:
verbose_name_plural = "Inventories"
inventory_name = models.CharField(max_length=100)
pub_date = models.DateTimeField('date published')
def __str__(self): # __unicode__ on Python 2
return self.inventory_name
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
class Block(models.Model):
class Meta:
verbose_name_plural = "Request Blocks"
inventory = models.ForeignKey(Inventory, null=True)
block_status = models.CharField(max_length=20, blank=False)
#617block_name = models.CharField(max_length=50, blank=False, null=False, validators=[block_nameTest])
block_name = models.CharField(max_length=50, blank=False, null=False)
block_derivatives = models.CharField(max_length=100)
block_subsystems = models.CharField(max_length=40)
owners = models.CharField(max_length=100)
def __str__(self):
return self.block_name
def block_owners(self):
return str(self.owners)
views.py:
from django.forms.models import modelformset_factory
from django.forms.formsets import formset_factory
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.views import generic
from django.http import HttpResponse
from django.shortcuts import render_to_response
from .models import Inventory, Block
from .forms import BlockForm
# Create your views here.
def requests(request, inventory_id):
BlockFormSet = formset_factory(BlockForm, extra=1)
inventory = get_object_or_404(Inventory, pk=inventory_id)
formset = BlockFormSet(request.POST)
if request.method == 'POST':
formset = BlockFormSet(request.POST)
if formset.is_valid():
for form in formset:
print form
form.save()
print "Success"
return HttpResponseRedirect('/inventory/2')
else:
print "Yo, this stuff is not validated"
else:
print "LOLOLOLOL"
return render(request, 'inventory/requests.html', {'inventory': inventory, 'formset': BlockFormSet})
requests.html:
{% block content %}
<div class="requestForm">
<form id="blockForm" class="original" action="{% url 'inventory:requests' inventory.id %}" method="post">{% csrf_token %}
<!-- <a href="#" id="insert-more"> Add New Row </a> -->
{{formset.management_form}}
{% for form in formset %}
<div class='item'>
<ul>{{ form.as_table}}<ul>
<p style=""><a class="delete" href="#">Delete</a></p>
</div>
{% endfor %}
<p><a id="add" href="#">Add another item</a></p>
<input type="submit" name="submit" value="Request Blocks" id="submitButton">
</form>
</div>
{% endblock %}
答案 0 :(得分:0)
您在POST无效后重定向,而不是重新显示相同的表单。即使您的重定向是相同的视图,它也会丢失POST数据,因此表单是空白的。
删除第一个else
块,让执行进入最后的render
行。