Custom user models don't like non integer primary keys.

313 views
Skip to first unread message

Eric Hutchinson

unread,
Nov 6, 2012, 1:43:27 PM11/6/12
to django-d...@googlegroups.com
I've been playing with custom user models. Something i've found is that trying to use the django-extensions uuidfield as a primary key doesn't seem very usable at the moment.

Many of the built in auth views, specifically password reset, assume an integer field here. 

/lib/python2.7/site-packages/django/utils/http.py", line 187, in int_to_base36
raise TypeError("Non-integer base36 conversion input.")
TypeError: Non-integer base36 conversion input.


Also, in the admin when creating a new user with the example admin setup from the docs, even though it would seem to have no reason to i get it trying to redirect to /app/model/(integer)/ when the id is clearly a uuid.

I know this isn't that helpful, but I don't know if this is just something you might want to warn about in the docs, or if this is something you want to fix in the built-in auth views, or what.

Jacob Kaplan-Moss

unread,
Nov 6, 2012, 2:19:10 PM11/6/12
to django-developers
Hey Eric --

Can you post the full traceback instead of just the snippet? Without
that it's not clear whether this is a bug or just a consequence of
defining your own custom user model. As the documentation notes:

"""

As you may expect, built-in Django's forms and views make certain
assumptions about the user model that they are working with.

If your user model doesn't follow the same assumptions, it may be
necessary to define a replacement form, and pass that form in as part
of the configuration of the auth views.
"""

So it might be the case that you just need to be customizing more
stuff to deal with your special model. Or not, but we probably need
more info to decide either way.

Jacob
Jacob
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/django-developers/-/VHk_gOF8DmEJ.
> To post to this group, send email to django-d...@googlegroups.com.
> To unsubscribe from this group, send email to
> django-develop...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/django-developers?hl=en.

Russell Keith-Magee

unread,
Nov 6, 2012, 6:06:43 PM11/6/12
to Django Developers
Hi Eric,

Although the full stack trace would confirm it, I think I can guess what the problem is here -- it's the mechanism for generating reset tokens. 

If you dig into the token generation (and reversal) mechanisms, they use int_to_base36 and base36_to_int to convert the user's primary key into something that can be used as a reversible, text-based identifier of the user object that isn't the literal identifier itself. This identifier is then used as part of the password reset token (along with a timestamp component and a component based on the last login timestamp)

A base36 encoding of an integer produces a nice reversible alphanumeric representation of the integer primary key that can be used in this reset token. 

So, yes -- non-integer primary keys will have a problem with any of the password reset or account activation logic. These should (he says, hopefully) be the only views that are affected.

One of the big features for Django 1.5 is the introduction of swappable user models. However, even with that change, we've maintained the requirement that the User model has an integer primary key

That said, I'm not personally opposed to dropping this requirement -- we just need to find a way to abstract the PK-dependent tokenization part in a useful way. As an initial thought, this is something that we could abstract out to the token generator API; the token generator is already customisable in the password reset views. However, I'm certainly open to other approaches.

Yours,
Russ Magee %-)

Bruno Renié

unread,
Nov 7, 2012, 4:41:30 AM11/7/12
to django-d...@googlegroups.com
The token generator API looks very similar to the cryptographic
signing API. The password reset views can be updated to use signing
instead. In fact I rewrote the password reset views using class-based
views and signing [0] and they ended up working very well even when
using an external authentication system instead of contrib.auth. I
also got rid of the base36 conversion in the process but this could be
added back with customization hooks.

It seems the auth views could benefit from such a conversion.

[0] http://pypi.python.org/pypi/django-password-reset

Bruno

Eric Hutchinson

unread,
Nov 9, 2012, 5:42:06 PM11/9/12
to django-d...@googlegroups.com
Sorry for disappearing there.

I didn't think a full trace was necessary, russ nailed that particular instance. As a user of django, I don't think for 1.5 that you need to change the behavior of views. It just blind sided me that the custom auth model needed an integer ID and it should be added to the docs before release. 

It'd be super nice if it worked with other field types, but I don't see it being a big deal if it's documented as being that way.

Tim Graham

unread,
Jun 25, 2013, 1:05:26 PM6/25/13
to django-d...@googlegroups.com
Ticket #14881 addresses the issue that django.contrib.auth assumes User.pk is an integer and thus password reset doesn't work. I've updated the original patch and added documentation and a backwards compatibility proposal. Reviews and feedback appreciated!
Reply all
Reply to author
Forward
0 new messages