0

在我的应用程序中,根据需要登录的用户,我有两个不同的登录页面。所以我不能使用settings.LOGIN_URL.

我也在使用基于类的视图,所以我必须使用method_decorator(login_required).

目前,我有一个类装饰器(我使用的是 Python 2.7),它几乎可以满足我的所有需求,除了login_url. 代码是一个片段并且是手工输入的,所以它可能有错字。

login_required_m = method_decorator(login_required)
def requires_role1(view):
  def requires_m(func):
    @wraps(func)
    def wrapper(self, request, *args, **kwargs):
      # I need to process request.user
      if (not ok):
        return redirect(urlresolvers.reverse('some_name'))
      else:
        f = login_required_m(func)
        return f(self, request, *args, **kwargs)
    return wrapper
  view.get = requires_m(view.get)
  view.post = requires_m(view.post)
  return view

我真正关心的是:

`f = login_required_m(func)`

在基于函数的视图中,我本来可以定义:

`f = login_required(func, login_url='some_reverse_path')`

但是有了method_decorator(login_required),我不再能够login_url作为参数传递。请记住,我需要能够这样做,因为我有两个不同的登录网址。它们提供完全不同的用户名和密码集(相同的用户名可以设置为不同的密码并与不同的人相关联)。

对于我应该做些什么来实现这一点的任何帮助将不胜感激。

编辑

根据接受的答案,这是我采用的解决方案:

def login_required_partial(func):
  return partial(login_required, login_url=urlresolvers.reverse('role1_login'))

login_required_m = method_decorator(login_required_partial)

并保持其余代码不变。当没有传递任何参数时,这一切似乎都运行良好ulr(r'path/(?P<param1>.*)', CBV.as_view(), name='path_name')

现在有人有解决这个问题的好方法吗?

4

2 回答 2

3

那这个呢:

class MyView(View):

  @method_decorator(lambda x: login_required(x, login_url=reverse_lazy('role1_login')))
  def post(self, request):
    return HttpResponse(status=200)

看起来这对我有用。

于 2014-08-14T23:22:02.430 回答
0

您可以装饰 CBV 视图功能:

# urls.py

from myproj.myapp import views

myview = login_required(views.MyView.as_view(), login_url=None)

urlpatterns = patterns('',
    url('^$', myview),
)

或者您可以创建某种混合:

from django.contrib.auth.decorators import login_required
from functools import partial

class LoginRequiredMixin(object):
    """
    A mixin used for views that can only be accessed by authenticated users.
    """

    login_url = None

    def _login_required(self):
        return partial(login_required, login_url=self.login_url)

    def dispatch(self, request, *args, **kwargs):
        def inner(*args, **kwargs):
            klass = LoginRequiredMixin
            return super(klass, self).dispatch(*args, **kwargs)

        return partial(inner, login_url=self.login_url)(request, *args, **kwargs)

并像这样使用它:

 # View class
 class MyView(LoginRequiredMixin, View):
     login_url = lazy_reverse('foo')

     pass

 # Or a view function in urls.py
 myview = views.MyView.as_view(login_url=reverse('foo'))
于 2012-10-24T17:59:49.607 回答