Python – Problems raising a ValidationError on a Django Form

cleaned-datadjangodjango-formspython

I'm trying to validate that a submitted URL doesn't already exist in the database.

The relevant parts of the Form class look like this:

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

The problem is, regardless of what value I submit, I can't raise the ValidationError. And if I do something like this in the clean_url() method:

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

then I get a DoesNotExist error, even for URLs that already exist in the Database. Any ideas?

Best Solution

django channel in IRC saved me here. The problem was that the URLField.clean() does two things I wasn't expecting:

  1. If no URL scheme is present (eg, http://) the method prepends 'http://' to the url
  2. the method also appends a trailing slash.

The results are returned and stored in the form's cleaned_data. So I was checking cleaned_data['url'] expecting something like example.com and actually getting http://example.com/. Suffice to say, changing my clean_url() method to the following works:

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')