python - Django - short non-linear non-predictable ID in the URL -


i know there similar questions (like this, this, this , this) have specific requirements , looking less-expensive way following (on django 1.10.2):

looking not have sequential/guessable integer ids in urls , ideally meet following requirements:

  • avoid uuids since makes url long.
  • avoid custom primary key. doesn’t seem work if models have manytomanyfields. got affected @ least 3 bugs while trying (#25012, #24030 , #22997), including messing migrations , having delete entire db , recreating migrations (well, lots of learning too)
  • avoid checking collisions if possible (hence avoid db lookup every insert)
  • don’t want slug since it’s less performant looking integer id.
  • don’t care encrypting id - don’t want visibly sequential integer.

note: app have 5 million records or in long term.

after researching lot of options on so, blogs etc., ended doing following:

  • encoding id base32 only urls , decoding in urls.py (using edited version of django’s util functions encode base 36 since needed uppercase letters instead of lowercase).
  • not storing encoded id anywhere. encoding , decoding everytime on fly.
  • keeping default id intact , using primary key.

(good hints, posts , this comment helped lot)

what solution helps achieve:

  1. absolutely no edits models or post_save signals.
  2. no collision checks needed. avoiding 1 request db.
  3. lookup still happens on default id fast. also, no double save()requests on model every insert.
  4. short , sweet encoded id (the number of characters go number of records increase still not long)

what doesn’t achieve/any drawbacks:

  1. encryption - id encoded not encrypted, user may still able figure out pattern id (but dont care much, mentioned above).
  2. a tiny overhead of encoding , decoding on each url construction/request perhaps that’s better collision checks and/or multiple save() calls on model object insertions.

for reference, looks there multiple ways generate random ids discovered along way (like django’s get_random_string, python’s random, django’s uuidfield etc.) , many ways encode current id (base 36, base 62, xoring, , not). encoded id can stored (indexed) field , looked every time (like here) depends on performance parameters of web app (since looking varchar id less performant looking integer id). identifier field can either saved overwritten model’s save() function, or using post_save() signal (see here) (while both approaches need save() function called twice every insert).

all ears optimizations above approach. love , community. everytime there’s learn here.


Comments

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

thorough guide for profiling racket code -