Django - URL中的短非线性不可预测的ID [英] Django - short non-linear non-predictable ID in the URL

查看:124
本文介绍了Django - URL中的短非线性不可预测的ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道有类似的问题(如这个),但是我有特定的要求,执行以下操作的较便宜的方法(在Django 1.10.2中):

I know there are similar questions (like this, this, this and this) but I have specific requirements and looking for a less-expensive way to do the following (on Django 1.10.2):

希望在URL中具有顺序/可猜测的整数并且理想地满足以下要求:

Looking to not have sequential/guessable integer ids in the URLs and ideally meet the following requirements:


  • 避免使用UUID,因为这使得URL真的很长。

  • 避免使用自定义主键。如果模型有ManyToManyFields,似乎不会很好的工作。在尝试时至少受到三个错误的影响(#25012 #24030 #22997 ),包括搞砸迁移,并且必须删除整个数据库并重新创建迁移(同样也是很好的学习)

  • 避免检查碰撞可能(因此避免每次插入的数据库查找)

  • 不要只是想查找s lug。since since。。。。。。。。。。。。。。。。。。。。。

  • 不要太在意加密ID - 只是不要让
    成为一个明显的顺序整数。

  • Avoid UUIDs since that makes the URL really long.
  • Avoid a custom primary key. It doesn’t seem to work well if the models have ManyToManyFields. Got affected by at least three bugs while trying that (#25012, #24030 and #22997), including messing up the migrations and having to delete the entire db and recreating the migrations (well, lots of good learning too)
  • Avoid checking for collisions if possible (hence avoid a db lookup for every insert)
  • Don’t just want to look up by the slug since it’s less performant than just looking up an integer id.
  • Don’t care too much about encrypting the id - just don’t want it to be a visibly sequential integer.

注意:该应用程序长期可能有500万条记录。

Note: The app would likely have 5 million records or so in the long term.

推荐答案

在研究了许多SO,博客等选项后,我最终做了以下工作:

After researching a lot of options on SO, blogs etc., I ended up doing the following:


  • 将ID编码为base32 ,并将其解码回urls.py(使用编辑过的Django版本的 util函数编码到基础36,因为我需要大写字母而不是小写)。

  • 不存储编码的id 任何地方

  • 保持默认ID不变,并将其用作主键。

  • Encoding the id to base32 only for the URLs and decoding it back in urls.py (using an edited version of Django’s util functions to encode to base 36 since I needed uppercase letters instead of lowercase).
  • Not storing the encoded id anywhere. Just encoding and decoding everytime on the fly.
  • Keeping the default id intact and using it as primary key.

(好的提示帖子,特别是评论帮助很多)

(good hints, posts and especially this comment helped a lot)

这个解决方案有助于实现: strong>

What this solution helps achieve:


  1. 绝对没有编辑模型或post_save信号。

  2. 不需要碰撞检查。避免对数据库的一个额外的请求。

  3. 查找仍然发生在默认的id是快速的。另外,对于每个插入,模型上没有double save()请求。

  4. 短而甜美的编码ID(随着记录数量的增加,字符数量增加,但仍不太长)

  1. Absolutely no edits to models or post_save signals.
  2. No collision checks needed. Avoiding one extra request to the db.
  3. Lookup still happens on the default id which is fast. Also, no double save()requests on the model for every insert.
  4. Short and sweet encoded ID (the number of characters go up as the number of records increase but still not very long)

它无法实现/任何缺点:


  1. 加密 - ID被编码但不加密,所以用户可以
    仍然能够找出模式来获取id(但是我不喜欢
    ,如上所述)。

  2. 对每个URL构造/请求进行编码和解码的一个微小的开销,但也可能比模型对象上的冲突检查和/或多个save()调用更为有效。

为了参考,看起来有很多种方法可以生成我发现的随机ID(如Django的 get_random_string ,Python的随机Django的 UUIDField 等)和许多方式来编码当前的ID(基础36,基础62,异或,而不是)。
编码的ID也可以存储为另一个(索引)字段,并且每次都会查找(如这里),但依赖于Web应用程序的性能参数(因为查找varchar id的性能较差,查找整数id)。该标识符字段可以从覆盖模型的save()函数中保存,也可以通过使用post_save()信号保存(参见这里)(而这两种方法都需要save()函数为每次插入调用两次)。

For reference, looks like there are multiple ways to generate random IDs that I discovered along the way (like Django’s get_random_string, Python’s random, Django’s UUIDField etc.) and many ways to encode the current ID (base 36, base 62, XORing, and what not). The encoded ID can also be stored as another (indexed) field and looked up every time (like here) but depends on the performance parameters of the web app (since looking up a varchar id is less performant that looking up an integer id). This identifier field can either be saved from a overwritten model’s save() function, or by using a post_save() signal (see here) (while both approaches will need the save() function to be called twice for every insert).

将耳朵优化到上述方法。我爱SO和社区。每次在这里学到很多东西。

All ears to optimizations to the above approach. I love SO and the community. Everytime there’s so much to learn here.

这篇关于Django - URL中的短非线性不可预测的ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆