views:

86

answers:

1

I have models similar to the following:

class Band(models.Model):
    name = models.CharField(unique=True)

class Event(models.Model):    
    name = models.CharField(max_length=50, unique=True)       
    bands = models.ManyToManyField(Band) 

and essentially I want to use the validation capability offered by a ModelForm that already exists for Event, but I do not want to show the default Multi-Select list (for 'bands') on the page, because the potential length of the related models is extremely long.

I have the following form defined:

class AddEventForm(ModelForm):
    class Meta: 
        model = Event
        fields = ('name', )

Which does what is expected for the Model, but of course, validation could care less about the 'bands' field. I've got it working enough to add bands correctly, but there's no correct validation, and it will simply drop bad band IDs.

What should I do so that I can ensure that at least one (correct) band ID has been sent along with my form?

For how I'm sending the band-IDs with auto-complete, see this related question: http://stackoverflow.com/questions/1528059/

+1  A: 

You can override the default fields in a ModelForm.

class AddEventForm(forms.ModelForm):
     band = forms.CharField(max_length=50)

     def clean_band(self):
         bands = Band.objects.filter(name=band,
             self.data.get('band', ''))
         if not bands:
             raise forms.ValidationError('Please specify a valid band name')
         self.cleaned_data['band_id'] = bands[0].id

Then you can use your autocomplete widget, or some other widget. You can also use a custom widget, just pass it into the band field definition: band = forms.CharField(widget=...)

synic
It seems that I need to create a new custom widget, specifically for this purpose... seeing as that, for this purpose, I am technically attempting to override the widget anyway. Makes sense.
anonymous coward