Friday, February 5, 2016

Re: ID for users of Speedy Net

The key is to start out your project with a different User model than the default model -- see https://docs.djangoproject.com/en/1.9/topics/auth/customizing/#specifying-a-custom-user-model . Create your own User model that inherits from AbstractBaseUser, and set AUTH_USER_MODEL = YourCustomUser.

It's key to do this at the beginning of the project, since it's really hard to migrate to this later. You can always change your custom model, but switching from the default to a custom model is nontrivial.

Remco Gerlich


On Fri, Feb 5, 2016 at 9:22 PM, Uri Even-Chen <uri@speedy.net> wrote:
Hi James,

Thanks for your feedback. My question was how do I change the primary key of a Django model such as User - a model I didn't write myself (it's already written by Django). Is it possible? Because I prefer the id/pk to be 15-digits randomly generated and not auto-increment. I don't see any logic in using auto-increment, I don't want the id/primary key to be short (such as zuck's id on Facebook - https://www.facebook.com/messages/4) but 15-digits long. And by the way, users who already signed up to Speedy Net already have a 15-digits id (randomly generated) and I want to preserve this id when converting Speedy Net from PHP/MySQL to Django and PostgreSQL.

I hope I clarified my question now.

Thanks,
Uri.

Uri Even-Chen  
photo Phone: +972-54-3995700
Email: uri@speedy.net
Website: http://www.speedysoftware.com/uri/en/
   

On Fri, Feb 5, 2016 at 8:22 PM, James Schneider <jrschneider83@gmail.com> wrote:


On Feb 4, 2016 10:59 AM, "Uri Even-Chen" <uri@speedy.net> wrote:
>
> Hi James,
>
> Thanks for your feedback. Actually I was thinking that this randomly generated number with 15 digits will be used in urls, for example of pages which don't have slugs etc. I saw similar urls in Facebook for pages who don't have a username (Facebook calls it a username), Facebook generates a slug which contains a 15-digits number. I found out that Facebook
redirects to this url when entering the url with only the number (for example https://www.facebook.com/342076035998592/ - with or without the trailing slash, even with several slashes). So the UUID will be too long for this, unless I generate it with 15 digits (decimal). And how do I make it a primary key of model User? Is there a way to change the primary keys of Django models and how? I think we will use PostgreSQL anyway, thanks!
>

You have total control over what field is used as the primary key.

https://docs.djangoproject.com/en/1.9/ref/models/fields/#primary-key

The model.id field that is automatically generated is for convenience and convention. It is not generated/available when a different primary key is specified, unless of course you name the field 'id'.

This is also why it is important to use model.ok when referring to the primary key for a model, rather than model.I'd, since model.pk is always made available as an alias to whatever primary key that the model it's using (be it an integer or a UUID).

Unless your code performs some operation on a model's primary key that is specific to an integer data type (ie using \d+ to look for primary keys in your urls.py), using model.pk is pretty universal and shouldn't require many changes to move from an integer to something else as your PK.

As far as the number that FB generates for their URL's, I'm sure it is some type of account number that is assigned upon creation, probably along the lines of what you were mentioning.

I suppose you could have the same ID between the two systems, but I wouldn't necessarily make that a hard requirement. It's pretty easy to add an extra correlation table that would keep track of the user in each system with a different PK. While this could incur an extra join or extra queries, it does make the system much more flexible, with the possibility to integrate with other authentication systems such as LDAP or Shibboleth where the customer may not be able to easily modify/add the DB attribute to match your account number/PK.

Also keep in mind that the PK and account number can, and probably should be, separate. Changing an account number (due to a typo, perhaps) could be disastrous if it were the PK, but there is little, if any, reason to manually update a true PK.

You could potential do some trickery with the PK to derive the account number, such as taking the existing PK and adding 1,284,386,269,433 to it, and using that value as the 'account' number. Using a nice even number like 1,000,000,000,000 makes the account number much more obvious, such as the first account being 1,000,000,000,001. Users will 'feel' better if they have a random-looking account number, although someone is bound to get 2,000,000,000,000 at some point.

You could also construct the account number through a series of organizational character positions to give the developer immediate information about the account just by looking at it, say all accounts created in 2016 will start with 16, with the numbers after that containing a department code, account type, etc. For example, an account starting with 1604 could mean that the account was created this year as a free account rather than a paid one. The remaining section of the account would be based on the PK of the user (assuming an integer PK).

I guess that's the long way of saying that the account number is part of your data, and should not be relied upon as part of your internal database structure (as a PK), especially when you have abstractions like model.pk available. If you want the account number, you should be asking for model.account_number anyway, not model.id or model.pk. Don't have coupling between your data and your infrastructure. You can still index and get the same searching benefits as a PK, so you don't gain much from it either, other than removing one minor abstraction while increasing complication immensely with related fields.

-James

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CA%2Be%2BciV0m0knMLYeBQtynXPufkVt35H8a%3DMF1AcAJ-DjO87Qcw%40mail.gmail.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CAMQ2MsGGA-uvWC338S%2BzDtWBDyKDK7QDxqxUqesdqjwtQA0%2BjQ%40mail.gmail.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CAFAGLK2wUpmyxvvsirjj9g3RD%3DwfaP2PJbLNOdFXoQ-Rb94ztQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment