from django.core.serializers.json import DjangoJSONEncoder from django.http import HttpResponse from django.utils import simplejson def ext_login(request): json = { 'errors': {}, 'text': {}, 'success': False, } user = authenticate(username=request.POST['username'], password=request.POST['password']) if user is not None: if user.is_active: login(request, user) json['success'] = True json['text']['welcome'] = 'Welcome, %s!' % (user.get_full_name(),) else: # Return a 'disabled account' error message json['errors']['username'] = 'Account disabled.' else: # Return an 'invalid login' error message. json['errors']['username'] = 'Username and/or password invalid.' return HttpResponse(simplejson.dumps(json, cls=DjangoJSONEncoder)) Sample Ext Panel config, uses Ext.ux.PasswordField (http://extjs.com/forum/showthread.php?t=20417): Signet.LoginForm = Ext.extend(Ext.FormPanel, { labelAlign: 'right' ,labelWidth: 75 ,title: 'Home' ,xtype: 'form' ,initComponent:function() { Ext.apply(this, { buttons:[ new Ext.Button({ handler: this.authSubmit ,scope: this ,text: 'login' }) ] ,items:[ new Ext.form.TextField({ fieldLabel: 'User Name' ,name: 'username' ,width: 100 }) ,new Ext.ux.PasswordField({ fieldLabel: 'Password' ,name: 'password' ,showCapsWarning: true ,showStrengthMeter: false ,width: 100 }) ] }); Signet.LoginForm.superclass.initComponent.apply(this, arguments); if (this.initialConfig.handler && this.initialConfig.scope){ this.form.on('actioncomplete', this.initialConfig.handler, this.initialConfig.scope); this.form.on('actionfailed', this.initialConfig.handler, this.initialConfig.scope); } } ,authSubmit: function(){ this.form.submit({ clientValidation: false ,method: 'POST' ,url:'/csds/ext/login/' }); } });