【问题标题】:Where to control permission-style viewing in Django? In the url (via generic views), template, or view?在哪里控制 Django 中的权限式查看?在 url(通过通用视图)、模板或视图中?
【发布时间】:2012-04-21 03:23:34
【问题描述】:

我有一个基本权限系统,其中我几乎是基于user.profile.user_type 对权限进行硬编码,其中user.profile 相当于user.get_profile()

例如,如果user_type1(物业经理),则该用户可以查看所有工作订单。 2user_type(租户)表示用户只能查看他创建的工单。

我目前只是像这样在urls.py 中使用基于类的通用视图

url(
    r'^orders/$',
    ListView.as_view(
        model = Order,
        template_name = 'doors/orders/list.html'
    ),
    name = 'orders_list'
),

因此我根本没有权限控制。

那么要添加权限系统,我应该在模板中这样控制吗?

{% for order in order_list %}
    {% if request.user.profile.user_type == 1 %}
        # Show every order
        {{ order.pk }}
    {% else %}
        # Show only work orders created by that user
        {% if order.creator == request.user.pk %}
            {{ order.pk }}
        {% endif %}
    {% endif %}
{% endfor %}

我有一种感觉,尝试在模板内部进行 filter 是在浪费大量的 SQL 命中,因为无论 user_type 是什么,模板仍然会强制 Django 调用每个工作指示。这是真的吗?

或者我应该像这样在视图中控制它?

def orders_list( request ) :
    if request.user.user_type == 1 :
        order_list = Order.objects.all()
    else :
        order_list = Order.objects.filter( creator = request.user.pk )

    dictionary = {
        'order_list' : order_list,
    }

    return render( request, 'doors/orders/list.html', dictionary )

显然,如果我尝试在 views.py 内控制它,那么我将无法再使用通用视图。

最后,我的第三个选择是(以某种方式)在基于类的通用视图中控制它。我什至不知道这是否可能。也许不知何故与get_context_data?我真的很喜欢通用视图的简单性,但我对更高级的 OO 概念不太熟悉。

你们有什么建议?

【问题讨论】:

  • 为什么不扩展通用视图类并添加自己的逻辑?

标签: python django permissions django-templates django-views


【解决方案1】:

如果您使用ListView,则有get_queryset() 方法可以做到这一点:

class OrderListView(ListView):
    template_name = 'doors/orders/list.html'

    def get_queryset(self):
        user = self.request.user
        if user.user_type == 1:
            return Order.objects.all()
        return Order.objects.filter(creator=user.pk)

【讨论】:

  • 感谢您的回复!一个简单的问题:如果我想获得总的Order 计数而不考虑权限(有点像 Stack Overflow 的统计数据:总共 2,904,397 个问题),我是否必须将其作为extra context 发送?似乎有很多代码只是为了向模板发送一个额外的变量。
  • 是的,你必须这样做。大多数人认为这是 CBV 的一个缺点,因为您需要编写大量垃圾代码。但另一方面,CBV 允许您在更易读的级别(queryset、context_data、dispatch 等)上拆分您的类,您可以将它们用作其他 View 类中的 Mixins
  • 您使用get_queryset 而不是简单地定义queryset = ... 有什么特别的原因吗?是不是因为不进入get_queryset函数就无法获取request.user信息?我只想定义queryset = ...,但我不确定如何获取用户信息。
  • queryset = 只是一个不依赖任何参数的参数,例如modeltemplate_name。在get_queryset 函数中,您可以将self 作为参数传递并指定其他逻辑
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-24
  • 2018-01-10
  • 1970-01-01
  • 1970-01-01
  • 2013-03-02
  • 2011-04-22
  • 1970-01-01
相关资源
最近更新 更多