问题描述
|
我有一个表单,管理员在其中输入一个逗号分隔的电子邮件地址列表,该表单在将每个电子邮件地址添加到数据库之前对其进行验证。使用我自己的(非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的形式构造此函数?如果是这样,我将如何完成这项任务?谢谢。
解决方法
在这种情况下,我不会使用
ModelForm
,因为它们是为要用一个Form表示一个Model实例的情况而设计的。在这里,您要使用一种形式生成多个实例。因此,只需编写一个带有自定义字段的通用表单(Django文档中就有一个为此示例的示例)以及一个自定义保存方法:
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 }