首页 > 解决方案 > Django url 操作 - 带有 pk / id 的详细信息页面不应基于该对象的属性显示 - 最佳实践

问题描述

我有一个显示链接列表的 django 页面。每个链接都指向相应对象的详细信息页面。该链接包含该对象的 pk/id(类似于 ../5/detailObject/)。该列表是在后端生成的,并有一些过滤功能,例如,仅当该对象具有状态 x 时才生成链接等。

单击链接有效,但用户仍然可以操纵 url 并传递具有不正确状态的有效链接(使用 get 或 404 快捷方式处理错误的 pk/id)。

用 django 处理这种情况的最佳实践是什么?这种过滤应该放在对象的模型类中,而不是像我现在那样使用基于函数的视图吗?

标签: djangopython-2.7

解决方案


基于函数的视图:

如果要将一组对象限制为特定用户(例如用户的订单),则需要将模型设置为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 库。我还没有使用它,但想在某个时候尝试一下。数据库字段选项将是我最不喜欢这样做的方式,因为在我看来,这就像将编程变量移动到数据库中一样;但是,它会起作用。


推荐阅读