2008-12-04 5 views
5

J'essaie de valider qu'une URL soumise n'existe pas déjà dans la base de données.Problèmes soulevés par ValidationError sur un formulaire Django

Les parties pertinentes du look classe Form comme celui-ci:

from django.contrib.sites.models import Site 
class SignUpForm(forms.Form): 
    # ... Other fields ... 
    url = forms.URLField(label='URL for new site, eg: example.com') 

    def clean_url(self): 
     url = self.cleaned_data['url'] 
     try: 
      a = Site.objects.get(domain=url) 

     except Site.DoesNotExist: 
      return url 

     else: 
      raise forms.ValidationError("That URL is already in the database. Please submit a unique URL.") 

    def clean(self): 
     # Other form cleaning stuff. I don't *think* this is causing the grief 

Le problème est, quelle que soit la valeur que je soumets, je ne peux pas soulever la ValidationError. Et si je fais quelque chose comme ça dans la méthode clean_url():

if Site.objects.get(domain=url): 
    raise forms.ValidationError("That URL is already in the database. Please submit a unique URL.") 

j'obtiens une erreur DoesNotExist, même pour les URL qui existent déjà dans la base de données. Des idées?

Répondre

4

canal django IRC m'a sauvé ici. Le problème était que le URLField.clean() fait deux choses je ne m'y attendais:

  1. Si aucun schéma d'URL est présent (par exemple, http: //) la méthode précèder « http: // » au url
  2. la méthode ajoute également un slash final.

Les résultats sont retournés et stockés dans le formulaire clean_data. Donc, je vérifiais cleaned_data['url'] s'attendant à quelque chose comme example.com et effectivement obtenir http://example.com/. Qu'il suffise de dire, de changer ma méthode clean_url() aux travaux suivants:

def clean_url(self): 
     url = self.cleaned_data['url']   
     bits = urlparse(url) 
     dom = bits[1] 
     try: 
      site=Site.objects.get(domain__iexact=dom) 
     except Site.DoesNotExist: 
      return dom 
     raise forms.ValidationError(u'That domain is already taken. Please choose another') 
1

Je le fais de cette façon. C'est un peu plus simple.

try: 
    a = Site.objects.get(domain=url) 
    raise forms.ValidationError("That URL is already in the database. Please submit a unique URL.") 
except Site.DoesNotExist: 
    pass 
return url 
+0

pas bon - L'erreur ne soit pas soulevée quand il le devrait. – saturdayplace

+0

Vous avez d'autres problèmes, alors. Cela doit fonctionner. Exécutez-vous "manage.py testserver" et obtenez une nouvelle base de données vide chaque fois que vous exécutez? Courez-vous "manage.py runserver"? –

+0

D'accord. Il y a de fortes chances que vos autres méthodes de validation soient en train de provoquer le chagrin. –

0

Je pense que vous pouvez retourner '' et remplir _errors.

msg = u"That URL is already in the database. Please submit a unique URL." 
self._errors["url"]=ErrorList([msg]) 
return '' 

ou

from django.contrib.sites.models import Site 
class SignUpForm(forms.Form): 
    # ... Other fields ... 

url = forms.URLField(label='URL for new site, eg: example.com') 

def clean_url(self): 
    url = self.cleaned_data['url'] 
    try: 
     a = Site.objects.get(domain=url) 
     raise forms.ValidationError("That URL is already in the database. Please submit a unique URL.") 
    except Site.DoesNotExist: 
     return url 
    return '' 

def clean(self): 
    # Other form cleaning stuff. I don't *think* this is causing the grief 
+0

-1: lever ValidationError est le bon moyen. Remplir self._errors manuellement est un hack sans raison valable. –

+0

+1: cela m'a quand même été utile – rplevy

Questions connexes