Djangoauthentication和Ajax – 需要login的URL

我想为我的Django编码的网站添加一些Ajax -niceness。

在我的Django代码中,我使用django.contrib.auth.decorators@login_required装饰器来标记哪个视图需要validation。 未经身份validation的用户单击默认行为是将其redirect到login页面,然后传递目标页面。

我在一些网站上看到的和真正喜欢的是,当用户点击一个链接到一个只限于login用户的地方,而不是被redirect到一个login页面,他/她得到一个popup窗口(通过JavaScript)询问他/她login或注册。 没有redirect部分,所以如果他/她确定他/她真的不喜欢该网站足以浪费注册时间,则不需要用户使用“返回”键。

所以,问题是:你将如何pipe理自动将某些链接标记为“受限”的任务,以便JavaScript可以处理其onclick事件并显示“请login”popup窗口?

我面临着同样的问题,和你一样,我想要一个简单的装饰器来包装一个Django ajax视图,以便像处理其他视图一样处理validation。 看起来很有希望的一种方法是将这样的装饰器与JavaScript一起使用,在响应中寻找一定的值。

这里是装饰者的第一修订草案:

 from functools import wraps def ajax_login_required(view_func): @wraps(view_func) def wrapper(request, *args, **kwargs): if request.user.is_authenticated(): return view_func(request, *args, **kwargs) json = simplejson.dumps({ 'not_authenticated': True }) return HttpResponse(json, mimetype='application/json') return wrapper 

这是观点:

 @ajax_login_required def ajax_update_module(request, module_slug, action): # Etc ... return HttpResponse(json, mimetype='application/json') 

这里是JavaScript(jQuery):

 $.post('/restricted-url/', data, function(json) { if (json.not_authenticated) { alert('Not authorized.'); // Or something in a message DIV return; } // Etc ... }); 

编辑 :我试图使用functools.wraps ,build议。 我实际上并没有在工作代码中使用这个装饰器,所以要小心可能的错误。

听起来像一个页面模板的可能性。

  1. 你可以通过一个LINK_VIA (或者你所提供的) onClick="return popup(this, 'arg')"None 。 每个链接将<A HREF="link" {{LINK_VIA}}>some text</a>

    • 对于匿名会话, LINK_VIA有价值。
    • 对于login会话, LINK_VIA是无
  2. 您可以在<A HREF=...>标记周围使用{% if %}语句。 这似乎罗嗦。

  3. 您可以使用{% link_via %}编写自己的自定义标签。 我对此不够熟悉,但是可以将链接和文本作为string提供,并且您的标记可以生成两种链接之一。

我同意S.Lott的意见

在模板中进行检查,如果用户login,只需像往常一样放置链接,如果没有,就把类似的东西

 <a href="{{link}}" onclick="return login_popup()"> 

如果用户说取消,login_popup将返回false。

在Jinja2中,通过它的macros可能会更容易。

如果模板不知道哪个url需要用户login,则可能需要重新考虑您的devise。

如果你必须,我想你可以做同样的事情,Django的url调度程序做的发现视图function。
请参阅: django.core.urlresolvers

一旦你抓住了查看function,你可以检查它是否用@login_required装饰。

这可能会在自定义标记中完成。
如果你使用Jinja2,你不需要标签,只需要实现这个function并将其暴露给环境,这很简单,但是你需要阅读Jinja的API,

这里是build议版本的装饰与包装.__ doc__,包装.__名称___

 from functools import wraps def ajax_login_required(function): def wrap(request, *args, **kwargs): if request.user.is_authenticated(): return function(request, *args, **kwargs) json = simplejson.dumps({ 'not_authenticated': True }) return HttpResponse(json, mimetype='application/json') wrap.__doc__ = function.__doc__ wrap.__name__ = function.__name__ return wrap