username > 30 characters?

110 views
Skip to first unread message

prote...@gmail.com

unread,
Feb 2, 2007, 7:43:38 PM2/2/07
to Django users
I'm re-engineering an existing directory application to use
Django. The application uses email addresses as the primary unique
userid. My understanding is that to map this to the Django User model
this needs to become the username. Unfortunately email addresses are
often longer than 30 characters. What would be the most pythonic way
to allow a username to be greater than 30 characters (and also support
valid email content rather than just isAlphaNumeric) that wouldn't
involve patching the Django source code (as I'd like to be able to
track the trunk updates frequently)?

thanx,

-- Ben

Vasily Sulatskov

unread,
Feb 4, 2007, 11:46:35 PM2/4/07
to Django users
Create your own authentication backend that uses emails instead of
usernames. Something like:

from django.contrib.auth.models import User

class BasicBackend:
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None


class EmailBackend(BasicBackend):
def authenticate(self, username=None, password=None):
try:
user = User.objects.get(email=username)
if user.check_password(password):
return user
except User.DoesNotExist:
return None

and add to settings.py

AUTHENTICATION_BACKENDS = (
'publicads.auth.EmailBackend',
)

Also I autogenerate usernames based on id, something like 'user_5454'.

Works for me

John Lee

unread,
Mar 26, 2007, 12:25:27 PM3/26/07
to Django users
It does work. However the "email" field of User should be set to
"blank=False" and "unique=True" if we really want to use email as the
unique userid. How can we override the default field definition of
User.email?

I tried something like this:

from django.contrib.auth.models import User as OldUser
#from django.db import models

class User(OldUser):
def __init__(self, *args, **kwargs):
super(User, self).__init__(*args, **kwargs)

#OldUser.email.blank=False
#OldUser.email.unique=True

class Admin:
pass

But the type of User.email is transferred to 'str' instead of
'CharField' so I'm stuck here.

Thanks.

-- John

Malcolm Tredinnick

unread,
Mar 26, 2007, 8:31:50 PM3/26/07
to django...@googlegroups.com
On Mon, 2007-03-26 at 16:25 +0000, John Lee wrote:
> It does work. However the "email" field of User should be set to
> "blank=False" and "unique=True" if we really want to use email as the
> unique userid. How can we override the default field definition of
> User.email?

You cannot override an existing class. In this case, you are going to
have to change the existing Django model. Sorry about that.

Regards,
Malcolm


Vasily Sulatskov

unread,
Mar 26, 2007, 10:29:37 PM3/26/07
to django...@googlegroups.com
> It does work. However the "email" field of User should be set to
> "blank=False" and "unique=True" if we really want to use email as the
> unique userid. How can we override the default field definition of
> User.email?

You can add unique constraint on email column on database level,
Django will be unaware of it, but at least database will guarantee
that emails will be unique.

--
Vasily Sulatskov

John Lee

unread,
Mar 28, 2007, 6:50:02 AM3/28/07
to Django users
I finally realized that simply inheriting a model will not work like I
expected. For example:

from django.core import validators


from django.contrib.auth.models import User as OldUser

from django.db import models

class User(OldUser):
def __init__(self, *args, **kwargs):
super(User, self).__init__(*args, **kwargs)

username = models.CharField(
_('username'), blank=True, maxlength=30, unique=False, \
validator_list=[validators.isAlphaNumeric], \
help_text=_("Required. 30 characters or fewer. Alphanumeric "\
"characters only (letters, digits and
underscores)."))

email = models.EmailField(_('e-mail address'), blank=False,
unique=True)

# additional fields, etc.

class Admin:
pass

class Event(models.Model):
def __str__(self):
return self.name

name = models.CharField(maxlength=100, blank=False)
attendants = models.ManyToManyField(User)
description = models.TextField()

class Admin:
pass

This will create a new mysite_user table and mysite_event_attendants
will refer to the correct foreign tables. However, under the /admin
site, the 'event' object still refer to 'auth_user' instead of
'mysite_user', and this will cause an error whenever you add/change/
delete.

Does that means the best I can do is to use 'auth' and 'admin' apps as
a simple admin backend, and build my own models/admin apps?

-- John

On Mar 27, 8:31 am, Malcolm Tredinnick <malc...@pointy-stick.com>
wrote:

Reply all
Reply to author
Forward
0 new messages