Saturday, October 31, 2009

Making the password field in Registration form

As shown in the register.html template file the "form" is sent by the handler to the template engine and we have not written the corresponding html. This html is generated based on the registration model we created.

In the registration model we have db.StringProperty as the type of the password field so the template engine renders a simple textbox for it and we would like to have a password field so user (or rather people looking at his screen) can not see the password being typed in this input field.

In django forms it is quite simple, you just have to say that the widget for this field should be PasswordInput as described here. Even though it is called djangoforms the functionalities are not quite similar at App Engine.

Here is how I solved it (with the help of information here) :

Extend db.StringProperty:

class PasswordProperty(db.StringProperty):
    def __init__(self, size=None, maxlength=None, password=False,
                 cssClass=None, **kwargs):
        self._size = size
        self._maxlength = maxlength
        self._password = password
        self._cssClass = cssClass
        super(PasswordProperty, self).__init__(**kwargs)

    def get_form_field(self, **kwargs):
        defaults = {}
        attrs={}
        if self._size:
            attrs['size']=self._size
        if self._maxlength:
            attrs['maxlength']=self._maxlength
        if self._cssClass:
            attrs['class']=self._cssClass
        if self._password:
            defaults['widget']=PasswordInput(attrs)
        else:
            defaults['widget']=TextInput(attrs)
        defaults.update(kwargs)
        return super(PasswordProperty, self).get_form_field(**defaults)

and now our model would look like this:

class RunAroundUser(db.Model):
    username = db.StringProperty(required=True)
    password = PasswordProperty(password=True,required=True)
    name     = db.StringProperty(required=True)
    email    = db.EmailProperty(required=True)
    fb_uid   = db.StringProperty()


Note that the password field is now of type PasswordProperty. I still need to refine the original idea that was here and then the PasswordProperty would be more refined and would not need to have "password=True" attribute.

1 comments:

Matt said...

Hey Kapil...

This is JUST what I was looking for... BUT after copy and paste... I am just not having luck with it...

I keep getting :

AttributeError: 'module' object has no attribute 'PasswordProperty'

at first I put the code that was extending String into a lib file but then moved it right above my model .. still no luck...

did you run into anything like that?

at any rate... what a nice write up... and on a subject that few know anything about...

( about me )
I am an old PERL / RUBY guy ( before RAILS )... and am in the midst of porting my first app ( webformtoemail.com ) over to app engine... just a little bit of the nice to have left to do... ( other than passwords... )

thx... mat

Post a Comment