我有一个表单,管理员可以在其中输入以逗号分隔的电子邮件地址列表,并且在将表单添加到数据库之前,表单会对每个电子邮件地址进行验证。使用我自己的(非django)表单,我能够做到这一点。我试图将其迁移到使用模型,但遇到了一些问题。这是我目前的代码 -
# model
class EmailList(models.Model):
email = models.EmailField(blank=True)
network = models.ForeignKey(Network)
class EmailListForm(ModelForm):
class Meta:
model = EmailList
def clean_email(self):
if self.cleaned_data['email']:
valid_emails = []
for x in self.cleaned_data['email'].split(','):
x = x.strip().lower()
valid_emails.append(x)
return valid_emails
# in views
def email(request):
if request.POST.get('email'):
for email in form.cleaned_data.get('email'): ### ??
if form.is_valid(): ### ??
EmailList.objects.create(email = email, network=Network.objects.get(id=request.POST['network']))
return redirect('.')
我遇到了麻烦,因为在表单验证之前我无法调用cleaned_data()
,但表单不会作为一个整体验证(只有迭代会)。是否可以使用django的表单构造此函数?如果是这样,我将如何完成这项任务?谢谢。
答案 0 :(得分:2)
在这种情况下,我不会使用ModelForm
,因为它们适用于您希望通过一个Form表示一个Model实例的情况。在这里,您希望使用一个表单生成多个实例。所以,只需用自定义字段编写一个通用表单(在Django docs中只有一个例子),也许是一个自定义保存方法:
from django import forms
from django.core.validators import validate_email
class MultiEmailField(forms.Field):
def to_python(self, value):
"Normalize data to a list of strings."
# Return an empty list if no input was given.
if not value:
return []
return value.split(',')
def validate(self, value):
"Check if value consists only of valid emails."
# Use the parent's handling of required fields, etc.
super(MultiEmailField, self).validate(value)
for email in value:
validate_email(email)
class EmailListForm(forms.Form):
emails = forms.MulitEmailField()
network = forms.ModelChoiceField(queryset=Network.objects.all())
# save the emails to the db
def save(self):
for email in self.cleaned_data.get('emails'):
EmailList.objects.create(email = email,
network=self.network)
# in views
def email(request):
if request.method == 'POST':
form = EmailListForm(request.POST)
if form.is_valid():
form.save()
return redirect(...somewhere...)
else:
form = EmailListForm()
return render(request, 'some/template.html', { 'form': form }