我有两种模式:
class Studio(models.Model):
name = models.CharField("Studio", max_length=30, unique=True)
class Film(models.Model):
studio = models.ForeignKey(Studio, verbose_name="Studio")
name = models.CharField("Film Name", max_length=30, unique=True)
我有一个电影表单,允许用户选择一个预先存在的Studio,或者输入一个新表单(在earlier question的帮助下:
class FilmForm(forms.ModelForm):
required_css_class = 'required'
studio = forms.ModelChoiceField(Studio.objects, required=False, widget = SelectWithPlus)
new_studio = forms.CharField(max_length=30, required=False, label = "New Studio Name", widget = DeSelectWithX(attrs={'class' : 'hidden_studio_field'}))
def __init__(self, *args, **kwargs):
super(FilmForm, self).__init__(*args,**kwargs)
self.fields['studio'].required = False
def clean(self):
cleaned_data = self.cleaned_data
studio = cleaned_data.get('studio')
new_studio = cleaned_data.get('new_studio')
if not studio and not new_studio:
raise forms.ValidationError("Must specify either Studio or New Studio!")
elif not studio:
studio, created = Studio.objects.get_or_create(name = new_studio)
self.cleaned_data['studio'] = studio
return super(FilmForm,self).clean()
class Meta:
model = Film
现在,我的第一个问题是当studio和new_studio都缺失时我得到一个django ValueError:无法分配无:“Film.studio”不允许空值错误。我以为我是捕获所有错误,因此django应该永远不会实现Film.studio是空的。
第二个问题是操作顺序。 如果我想在我确定FilmForm的其余部分有效之后才想保存new_studio怎么办(这样可以防止在完整的电影条目通过之前保存一堆工作室名称)?我是明确的还是我冒着过早保存的风险,因为new_studio被保存在表格的清洁中?
修改:添加了Traceback并编辑了验证if-statements
答案 0 :(得分:2)
从cleaning_data删除工作室和 new_studio 。
if not studio and not new_studio:
del cleaned_data['studio'], cleaned_data['new_studio']
raise forms.ValidationError("Must specify either Studio or New Studio!")
答案 1 :(得分:1)
关于防止new_studio投降的费用:
新的def清洁形式: def clean(self): cleaning_data = self.cleaned_data studio = cleaning_data.get('studio') new_studio = cleaning_data.get('new_studio')
if not studio and not new_studio:
del cleaned_data['studio'], cleaned_data['new_studio']
raise forms.ValidationError("Must specify either Studio or New Studio!")
elif not studio:
del cleaned_data['studio']
return super(FilmForm,self).clean()
在视图中:
def testone(request):
if request.method == 'POST': # If the form has been submitted...
form = FilmForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
if form.cleaned_data['new_studio']:
studio, created = Studio.objects.get_or_create(name = form.cleaned_data['new_studio'])
new_film = form.save(commit=False)
new_film.studio = studio
else:
new_film = form
new_film.save()
return HttpResponseRedirect('/') # Redirect after POST
else:
form = FilmForm() # An unbound form
return render_to_response('testone.html', {
'form': form
}, context_instance=RequestContext(request))