I have two models:
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)
I have a Film form that allows the user to either select a preexisting Studio, or type in a new one (with help from an 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
Now, my first issue is that when both studio and new_studio are missing I get a django ValueError: Cannot assign None: "Film.studio" does not allow null values error. I thought I was capturing all the errors, thus django should never get so far as to realize Film.studio is empty.
A second issue is an order of operations. What if I want to only save the new_studio after I'm sure the rest of the FilmForm is valid (thus preventing a bunch of studio names getting saved before full Film entries go through as well)? Am I in the clear or do I risk premature saving because new_studio's are saved in the form's cleaning?
Edit: Added Traceback and edited validation if-statements
if studio is None and new_studio == '':. Could studio be''or new_studio beNone? Does it correctly show the form error if you change that toif not (studio or new_studio):?ifandelifchecks? The one's your using now open up holes in the logic that allows certain scenarios to fall through unchecked. Should've stuck to what I gave you. Additionally, thecleanmethod is only ran after the individualclean_FIELDmethods are run, so effectively, you only reach this point if everything else is valid. You don't have to worry about Studios getting created when there's other problems in the form still.