url design:从url隐藏pk / id的方法

时间:2012-03-27 20:19:20

标签: python django url

要访问我网站上的项目的详细信息页面,可以使用以下网址

<mydomain>/item/1

其中1是项目的主键

我正在寻找一种解决方案,允许我重新设计具有以下要求的网址:

  • 从网址
  • 中排除pk或任何连续的ID
  • 能够唯一访问项目详细信息页面

我打算将此问作为一般网页设计问题,但我想应该提一下我正在使用Python / Django。

5 个答案:

答案 0 :(得分:7)

您需要在网址中包含某种类型的标识符,并且此标识符为:

  1. 必须是唯一的(没有两个对象可以具有相同的ID)
  2. 必须是永久性的(对象的id永远不会改变)
  3. 所以没有那么多选项,对象的主键是最佳选择。如果由于某种原因你不能使用它(为什么不呢?)你可以编码或混淆它:请参阅this question及其答案,了解如何做到这一点。

    Stack Overflow自己的URL设计值得一看。您可以通过表格的任何网址

    来解决此问题
      

    https://stackoverflow.com/questions/9897050/any-text-you-like-here!

    这允许URL包含问题标题中的关键字(针对搜索引擎),同时还可以在标题更改时更改而不会破坏旧链接。

答案 1 :(得分:5)

我不喜欢slugfield选项,因为它会向数据库添加一个额外的查询。

我在一个项目中做了以下事情:

我的网址如下:

<domain>/item/5927/728e26e9464a171b228bc9884ba3e4f76e2f8866/

这是:

<domain>/item/<id>/<hash>/

如果您不知道哈希,则无法访问该项:

urls.py:

url(r'^item/(?P<id>\d+)/(?P<hash>\w+)/$', 'rwapp.views.item', name='item')

views.py:

from hashlib import sha1

def item(request,id=None,hash=None):
    if not id:
        return HttpResponseRedirect("/home")
    if hash:
        chash = sha1("secret_word%s"%id).hexdigest()
        if not chash==hash:
            return HttpResponseRedirect("/home")
    else:
        return HttpResponseRedirect("/home")

当然,每次渲染URL时都必须添加//部分。

答案 2 :(得分:4)

有很多方法可以做到这一点。由于您使用的是django,请查看SlugField。或者您生成UUID并将其存储在每个项目上以供访问。

答案 3 :(得分:4)

对于Django,您可以为模型添加SlugField,然后让视图使用该模型查找模型。

MyModel.objects.filter(slug_field_name='some-slug-value')

确保有一些形式的唯一性约束。

答案 4 :(得分:0)

这样做的一种肮脏方式是使用cookie来保存所请求对象的id。我并不特别喜欢这个想法,除非你有编写/扩展框架的经验,否则可能很难获得支持框架。

某些框架支持使用id = attribute而不是您的URL路径。如果将其作为POST参数包含在内,则它将不可见,但将页面与POST链接起来将具有挑战性,因为它用于提交表单数据。

我建议的方法是使用除了id之外的东西来唯一地标识你的对象,如果这是一个真正的要求。然后在您的网址中包含该内容。虽然从数据库的角度来看这不是一个理想的设计,但确实有其优点。首先,您必须考虑为什么要隐藏此信息。如果是出于搜索引擎优化的目的,使用项目的名称而不是其ID是您想要的URL。真正的问题是,如果您只是将这些信息隐藏在其他数据通道中,那么您将拥有不同资源的相同URL。这是次要的,原因很多,其中最重要的是SEO和用户书签。使用人类可读的密钥可以解决这两种情况,同时可以解决您的DBA问题。使用此方法也可以直接在框架中轻松地工作,也可以使用控制器中的其他代码进行转换,这可能会使您在DBA中正确使用。

相关问题