views:

110

answers:

3

Hi all,

Firstly, this is not the question how to authenticate on email/password pair, but rather how to produce logical, and if you like, beautiful data structure.

I want to use emails as user names in a given django project. However, I am unable to re-use fields provided by auth.User model for at least two reasons:

  1. auth.User.username 's field max_length is 30 characters, which might not be enough for some email addresses.

  2. auth.User.email is not unique - which is obviously not satisfactory for a prerequisite saying that user names have to be unique.

So an obvious way here is to store username in a custom profile, which is linked to auth.User. In this case we have to deal with following problems:

  1. Generate unique username for auth.User.username - md5 hash of email should be fine here?
  2. Leave out completely auth.User.email empty - since it's only 75 characters long, while according to RFC 5321 (http://stackoverflow.com/questions/386294/maximum-length-of-a-valid-email-id) email can be as long as 256 characters.

The following problems stem from the proposed solution:

  1. One is not going to be able to reuse built-in views/templates for standard operations like password reset etc
  2. In case of email change auth.User.username will have to be updated

To add oil into the fire, django developers are not likely to fix this limitation in any foreseeable future - see http://code.djangoproject.com/ticket/11365

So the question is: is there any other way to do it and do you see any other drawbacks in the solution proposed above?

Thanks!

+2  A: 

You might want to take a look at how Satchmo handle this problem :

http://bitbucket.org/chris1610/satchmo/src/tip/satchmo/apps/satchmo_store/accounts/email-auth.py

and

http://bitbucket.org/chris1610/satchmo/src/533a63f955f8/satchmo/apps/satchmo_utils/unique_id.py

kemar
It uses User.email in authentication, which is wrong (see length limitation)
Art
+4  A: 

I had a client with a commercial site that had been up since 1995 (yeah, we're talking early adopters here). Anyway, they already had an established user base and the names were totally non-compliant with Django's idea of a username.

I looked at a few ways to handle it and they all felt like hacks (this was Summer of 2007), so I said screw it and hacked contrib.auth.models.User directly. I only had to change about 10 lines of code, increase the field size, and tweak the validator. We've done two upgrades since then -- 0.97-pre => 1.0, and 1.0 => 1.1.1 -- and it's only taken about 15 minutes each time to "port the hack".

It isn't pretty, and I may burn in Hell for doing it like this, but it took less time to do it this way than anything else I could figure out and the forward ports have been a total non-issue.

Peter Rowell
Yup, that's definitely the stuff that'll get you to burn in hell xD!
kRON
A: 

I too must confess that I'll burn in hell. I've recently deployed a small app where I slugified the user's e-mail, sliced it to 30 characters and set that as the username. I thought hell, what are the odds? and went through with it. Took a few lines of code and voila.

I think the 75 character cap has been set as such because people usually don't have personal e-mails that long. That's just a matter of space conservation, because all those unused bytes will get reserved anyways (i.e. NULL and shorter/smaller values aren't free).

kRON
I don't think it's a space issue per se, at least as far as database is concerned - there's VARCHAR type in most of them, imho.
Art
I believe the memory gets reserved, so that all the column values have a fixed length to make the lookup faster.
kRON
@kRON: No. "VARCHAR data types are popular ... because, unlike the fixed-size char data-type, varchar does not store any blank characters, reducing the size of a database when the full length of the field is not used, although the length of the used size is stored, adding a small overhead." http://en.wikipedia.org/wiki/Varchar
parxier
Thanks, I didn't know that!
kRON