2010-05-11 6 views
1

J'ai des modèles similaires à ce qui suit:Validation d'un champ Autocomplete dans Django

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) 

et essentiellement je veux utiliser la capacité de validation offerte par un ModelForm qui existe déjà pour l'événement, mais je ne pas veulent pour afficher la liste multi-sélection par défaut (pour les 'bandes') sur la page, car la longueur potentielle des modèles associés est extrêmement longue.

Je la forme suivante définie:

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

Ce qui fait ce qu'on attend pour le modèle, mais bien sûr, la validation se fout du champ « bandes ». Je l'ai assez de travail pour ajouter des bandes correctement, mais il n'y a pas de validation correcte, et il va simplement laisser tomber les bad band IDs.

Que dois-je faire pour que je puisse m'assurer qu'au moins un ID de bande (correct) a été envoyé avec mon formulaire?

Pour que je vous envoie la bande-ID avec auto-complétion, voir cette question connexe: Django ModelForm Validate custom Autocomplete for M2M, instead of ugly Multi-Select

Répondre

1

Vous pouvez remplacer les champs par défaut dans un 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 

Ensuite, vous pouvez utiliser votre widget de saisie semi-automatique, ou un autre widget. Vous pouvez également utiliser un widget personnalisé, il suffit de le passer dans la définition de champ de bande: band = forms.CharField(widget=...)

+0

Il semble que j'ai besoin de créer un nouveau widget personnalisé, spécifiquement à cet effet ... vu que, à cette fin, je suis techniquement tenter de contourner le widget de toute façon. Logique. –