django - Django url 操作 - 带有 pk / id 的详细信息页面不应基于该对象的属性显示 - 最佳实践
问题描述
我有一个显示链接列表的 django 页面。每个链接都指向相应对象的详细信息页面。该链接包含该对象的 pk/id(类似于 ../5/detailObject/)。该列表是在后端生成的,并有一些过滤功能,例如,仅当该对象具有状态 x 时才生成链接等。
单击链接有效,但用户仍然可以操纵 url 并传递具有不正确状态的有效链接(使用 get 或 404 快捷方式处理错误的 pk/id)。
用 django 处理这种情况的最佳实践是什么?这种过滤应该放在对象的模型类中,而不是像我现在那样使用基于函数的视图吗?
解决方案
基于函数的视图:
如果要将一组对象限制为特定用户(例如用户的订单),则需要将模型设置为Order
模型的外键User
,然后通过 id 和用户查找订单:
视图.py:
def get_order(request, id=0)
if request.method == 'GET':
try:
order = Order.objects.get(user=request.user, pk=id)
except Order.DoesNotExist:
return redirect(...)
并设置一个url来处理:
url(r'^order/(?P<id>\d+)/$', views.get_order, name='get_order_by_id'),
至于事后在模型上添加一个 slug 字段,设置第二个 url:
url(r'^order/(?P<slug>[\w-]+)/$', views.get_order, name='get_order_by_slug')
并将上面的视图逻辑更改为如果 pk 大于 0,则首先通过 pk 进行查找,然后使用查找顺序中的 slug 重定向回函数(假设所有查找的记录都有 slug):
def get_order(request, slug='', id=0)
if request.method == 'GET':
try:
if id > 0:
order = Order.objects.get(user=request.user, pk=id)
return redirect(reverse('get_order_by_slug'), permanent=True, slug=order.slug)
order = Order.objects.get(user=request.user, slug=slug)
except Order.DoesNotExist:
return redirect(...)
您还应该放置unique=True
字段并通过将装饰器放置在您的视图slug
上来确保用户已通过身份验证。@login_required
要按特定状态限制订单,您可以:
为您的 Order 模型创建一组状态,然后您可以:
- 过滤时在视图中传递一个 kwarg 的值,或者
- 在 Order 模型上创建自定义管理器
有几种方法可以创建您的状态:
Order
作为模型上的一组选择- 使用SmartChoices库
- 作为数据库字段
如果您在Order
模型上创建选择,它可能是这样的:
class Order(models.model):
STATUSES = (
('PLCD', 'Placed'),
('INTR', 'In Transit'),
('DLVR', 'Delivered')
)
status = models.CharField(max_length=4, default='', choices=STATUSES)
一位经验丰富的 Django 专业人士向我介绍了 SmartChoices 库。我还没有使用它,但想在某个时候尝试一下。数据库字段选项将是我最不喜欢这样做的方式,因为在我看来,这就像将编程变量移动到数据库中一样;但是,它会起作用。
推荐阅读
- r - 如何在限制 conditionalPanel() 的可访问性的同时保持可见性?
- android - 使用 FFmpeg 的视频压缩在 android 10 上不起作用
- google-bigquery - 在 BigQuery 中将数据插入/创建分片/通配符表
- extjs - 当 ExtJS 6.7 中的第一个数字为 0 时,datepickerfield 自动切换日期和月份
- azure - Set-AzActionGroup:异常类型:ErrorResponseException
- python-3.x - 仅在 python 中打印前 25 个索引
- azure - 带有 AAD 的 Azure SQL DB - 有没有办法获得只读访问权限
- vb.net - API REST Verbe 类型使用 GET 而不是 POST
- sql - 我们如何在 SQLITE 中将 clob 字段的子字符串转换为日期时间?
- python - 在python中将二进制图像缩小到非零区域