【发布时间】:2012-04-11 10:16:03
【问题描述】:
要访问我网站上某个项目的详细信息页面,可以使用以下网址
<mydomain>/item/1
1 是 Item 的主键
我正在寻找一种解决方案,让我可以根据以下要求重新设计 url:
- 从 url 中排除 pk 或任何顺序 ID
- 能够唯一访问项目详细信息页面
我打算将这个问题作为一个一般性的网页设计问题来问,但只是想我应该提到我正在使用 Python/Django。
【问题讨论】:
要访问我网站上某个项目的详细信息页面,可以使用以下网址
<mydomain>/item/1
1 是 Item 的主键
我正在寻找一种解决方案,让我可以根据以下要求重新设计 url:
我打算将这个问题作为一个一般性的网页设计问题来问,但只是想我应该提到我正在使用 Python/Django。
【问题讨论】:
我不喜欢 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 时都必须添加 // 部分。
【讨论】:
你需要在 URL 中有 一些 种标识符,并且这个标识符:
所以没有那么多选项,对象的主键是最好的选择。如果由于某种原因您不能使用它(为什么不呢?),您可以对其进行编码或混淆:请参阅this question 及其答案,了解有关如何执行此操作的一些想法。
Stack Overflow 自己的 URL 设计值得一看。您可以通过表单的任何 URL 找到此问题
https://stackoverflow.com/questions/9897050/any-text-you-like-here!
这允许 URL 包含来自问题标题的关键字(用于搜索引擎),同时还能够在标题更改时更改而不破坏旧链接。
【讨论】:
这样做的一种肮脏方式是使用 cookie 来保存被请求对象的 id。我不是特别喜欢这个想法,除非你有编写/扩展框架的经验,否则很难获得一个框架来支持。
一些框架支持使用 id= 属性而不是 URL 路径。如果将其作为 POST 参数包含在内,它将不可见,但将页面与 POST 链接在一起将具有挑战性,因为它旨在提交表单数据。
我建议的方法是,如果这是一个真正的要求,则使用除 ids 之外的其他东西来唯一标识您的对象。然后将其包含在您的 URL 中。虽然从数据库的角度来看这不是一个理想的设计,但它确实有好处。首先,您必须考虑为什么要隐藏此信息。如果是出于 SEO 目的,则在 URL 中使用项目名称而不是其 id 是您想要的。真正的问题是,如果您只是将此信息隐藏在其他一些数据通道中,那么您对于不同的资源就有相同的 URL。由于许多原因,这低于标准,其中最重要的是 SEO 和用户书签。使用人类可读的密钥可以解决两种情况和其他情况,同时激怒您的 DBA。使用这种方法也应该很容易直接或通过在控制器中使用额外的代码来进行转换,这可能会让您与 DBA 建立正确的关系。
【讨论】:
对于 Django,你可以给你的模型一个SlugField,然后让视图使用它来查找模型。
MyModel.objects.filter(slug_field_name='some-slug-value')
确保上面有某种形式的唯一性约束。
【讨论】:
嗯,有很多方法可以做到这一点。由于您使用的是 django,请查看SlugField。或者您生成 UUID 并将其存储在每个项目上以供访问。
【讨论】: