import types from django import forms class DynamicAttrsForm(forms.ModelForm): class Meta: model = models.DynamicAttrs fields = ['template', 'mood', 'text' ] def __init__(self, *args, **kwargs): super(DynamicAttrsForm, self).__init__(*args, **kwargs) # This method generator must leave out of the for loop, # and must return an indirected function, else bad things # will happen. def clean_sample_wrapper(sstype): def clean_sample_generic(self): sample = self.cleaned_data[sstype] if sample.mood != self.cleaned_data['mood']: raise forms.ValidationError( '%(sstype)s is not a sample of the selected mood!', params={'sstype': sstype}) return sample return clean_sample_generic for stid, stype in models.SAMPLE_TYPE_CHOICES.items(): stype = unicode(stype).lower() sstype = str(stype) queryset = models.Sample.objects.filter( is_published=True, conv_status=1, type=stid ).order_by('name') if self.instance.pk: self.fields[sstype] = forms.ModelChoiceField( label=stype, queryset=queryset, initial=self.instance.sample_set.get( sample__type=stid).sample.pk) else: self.fields[sstype] = forms.ModelChoiceField( label=stype, queryset=queryset) setattr(self, 'clean_{0}'.format(stype), types.MethodType(clean_sample_wrapper(sstype), self))