Insert AUTOMATICALLY random string in username field

254 views
Skip to first unread message

nameless

unread,
Jan 14, 2010, 9:45:13 AM1/14/10
to Django users

I want username field is automatically filled with this value:

username = str(n);

where n is a number of 10 digits ( autoincremented or random ).

.

I tried to add this in save method:

username = str(random.randint(1000000000,9999999999))

but there is a collision problem when n is the same for 2 users
( although rare initially ).

.

How do I do this ?

Thanks ^_^

Stephen Emslie

unread,
Jan 14, 2010, 9:48:44 AM1/14/10
to django...@googlegroups.com
How about a timestamp?

  import time
  name = str(time.time())

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.




Shawn Milochik

unread,
Jan 14, 2010, 10:16:16 AM1/14/10
to django...@googlegroups.com
There are a bunch of ways you can do it. As a previous poster said, you can take 10 digits of the current timestamp. However, be wary of daylight saving time changes (if you have them on your server), and the possibility of any conflict if you change servers, have a backup server, or ever expand to multiple servers for your application.

A possibility, if you're open to alphanumeric strings, is a uuid, specifically uuid4 or uuid1. Check out the documentation to see if they'd work for you. If you don't care to necessarily limit it to 10 characters, and you don't mind alpha-numeric characters, then just use a uuid4 and you're done.
http://docs.python.org/library/uuid.html

Yet another possibility is to use the capability of your database to create sequences. If you're using Postgres, it has a SEQUENCE which you can create, and always ask it for the next one. You can start a sequence at any number you like, in order to get the size you want. We do something similar for generating customer numbers. We have a sequence, and we use it appended to a static set of digits for the particular program the customer is in. So, for example, all customers in program X would have a customer number of 10 digits starting with '1001' and ending with an incremental number. There are ways to do this with other databases. Worst-case you can create a table with an auto-increment key and just use its primary key for your next digit.

One more, but not last nor least, is to have your model generate the string you want by one of the means above, or something completely different, then override the save() of your model to check to ensure that this key doesn't exist already. This is less than ideal, but maybe there's a case to be made for it. Just throwing it in as an option.

Shawn

nameless

unread,
Jan 14, 2010, 10:41:42 AM1/14/10
to Django users
Sequences are best solution for me but I don't know how to implement
its in django+mysql.
I tought also to use id as username but I don't know how do this :-\

Could you explain me how do pleaseeeeeee ?
Thank you


---------------


On Jan 14, 4:16 pm, Shawn Milochik <sh...@milochik.com> wrote:
> There are a bunch of ways you can do it. As a previous poster said, you can take 10 digits of the current timestamp. However, be wary of daylight saving time changes (if you have them on your server), and the possibility of any conflict if you change servers, have a backup server, or ever expand to multiple servers for your application.
>

> A possibility, if you're open to alphanumeric strings, is a uuid, specifically uuid4 or uuid1. Check out the documentation to see if they'd work for you. If you don't care to necessarily limit it to 10 characters, and you don't mind alpha-numeric characters, then just use a uuid4 and you're done.http://docs.python.org/library/uuid.html

Shawn Milochik

unread,
Jan 14, 2010, 11:15:42 AM1/14/10
to django...@googlegroups.com
Do a Google search on 'mysql' and 'sequences.'

Also, have a look at MySQL's last_insert_id() function. Maybe that's
all you need to use an autonumber as a sequence.

Shawn

Tom Evans

unread,
Jan 14, 2010, 11:29:16 AM1/14/10
to django...@googlegroups.com
On Thu, Jan 14, 2010 at 2:45 PM, nameless <xsate...@gmail.com> wrote:
>
>

Use a version 4 UUID instead. If you generate 1 billion version 4
UUIDs a second for 100 years, you have ~ 50% chance of a collision.
They are also built in to later versions of python (2.5+):

>>> import uuid
>>> print uuid.uuid4()
92d6a4f4-918d-4a9b-8251-3150c88c62e7


Cheers

Tom

nameless

unread,
Jan 14, 2010, 1:34:27 PM1/14/10
to Django users
uuid is too long for username field ( max 30 characters ). "n" should
be a number of 10 digits :)


----------------

On Jan 14, 5:29 pm, Tom Evans <tevans...@googlemail.com> wrote:

Tom Evans

unread,
Jan 14, 2010, 2:20:02 PM1/14/10
to django...@googlegroups.com
On Thu, Jan 14, 2010 at 6:34 PM, nameless <xsate...@gmail.com> wrote:
> uuid is too long for username field ( max 30 characters ). "n" should
> be a number of 10 digits :)
>
>

Er, a UUID is a 128 bit number. In its standard 'for humans' format it
is represented as 36 character hexadecimal string (ie 288 bits), but
how you pack that into your database is your concern - here is a way
to ensure a 24 character ascii UUID:

>>> import base64
>>> import uuid
>>> print base64.b64encode(uuid.uuid4().bytes)
y1WjDxxOT0KQVe4Jkwuj2g==
>>> print len(base64.b64encode(uuid.uuid4().bytes))
24

although django will still barf on that, it wont accept '/', '=' or
'+' as part of a username - a really pointless and arbitrary
validation rule imo.

Cheers

Tom

Eric Chamberlain

unread,
Jan 14, 2010, 3:29:49 PM1/14/10
to django...@googlegroups.com

We did something like:

def register_user(email, password, first_name=None, last_name=None, agree_to_eula=True):

def generate_username():
"""Generate a random 30-character username. Username can only be alphanumeric or underscore."""
return ''.join([choice(string.letters + string.digits + '_') for i in range(30)])

email = email.strip()
if not email_re.search(email):
raise InvalidEmailAddressExcept

if len(password.strip()) < 6:
#TODO: pass password length info back to exception, so it's not hard coded in two locations
raise InvalidPasswordExcept

try:
user = authenticate_user(email,password,agree_to_eula)
except AuthenticationFailedExcept:
raise AccountExistsAuthenticationFailedExcept
except UserNotFoundExcept:
# we need to create this user
while True:
try:
user = User.objects.create_user(username=generate_username(),
email=email, password=password)
except IntegrityError:
# this means the username already exists loop and try again with a new username
continue
else:
# we successfully created the user, leave the loop
break

if first_name:
user.first_name = first_name
if last_name:
user.last_name = last_name
user.save()
profile = Profile(user=user)
if agree_to_eula:
profile.agree_to_eula()
profile.save()
else:
profile = user.get_profile()

return {'user': user,}

Reply all
Reply to author
Forward
0 new messages