views:

3897

answers:

2

I am trying to create a custom form field and validate off it. This is version 1.0 of Django.

Here is my form object

class UsernameField(forms.CharField):
    def clean(self, values):
        print ""

Here is how I call it

class RegisterForm(forms.Form):
   username = UsernameField(max_length=30, min_length=4)
   password = forms.CharField(widget = forms.PasswordInput(), min_length=5)
   password2 = forms.CharField(widget = forms.PasswordInput(), min_length=5)
   email = forms.EmailField(max_length=75)

Now I want to keep the default min/max_length checks for a CharField in tack.. but I can't seem to figure how how to do that.

If I put any code into clean() those are not checked. If i try to call parent.clean() i get an error.

+1  A: 

That didn't work in 1.0... here is how I solved it

class UsernameField(forms.CharField):
    def clean(self, request, initial=None):
        field = super(UsernameField, self).clean(request)

        from django.contrib.auth.models import User
        user = User(username=request)
        if user is not None:
            raise forms.ValidationError("That username is already taken")
Fine solution, bad question :-) Nowhere in your question did you explain what you were actually trying to accomplish.
Carl Meyer
+7  A: 

If you just want to clean your field, there's no need to define a whole new field, you can do that in the form's clean_username method

class RegisterForm(forms.Form):
  username = forms.CharField(max_length=30, min_length=4)
  ...
  ...

  def clean_username(self):
    username = self.cleaned_data['username']
    try:
        user = User.objects.get(username=username)
    except User.DoesNotExist:
        return username
    raise forms.ValidationError(u'%s already exists' % username )

  def clean(self):
    # Here you'd perform the password check
    ...

You might also consider using django-registration for user registration in Django, it takes care of this in a pluggable app, which will handle all the user validation, creation and setup for you.

As for the new firld creation, your field's clean() method should return a cleaned value, not just print it.

class MyField(forms.CharField):
  def clean(self, value):
    # perform cleaning
    return value
Jj