这是我的管理视图,我需要一个装饰器代替“event_session_check”,但我不知道如何将“event_key”传递给装饰器,所以我写了“event_session_check”......
“event_session_required”将验证EventSet模型中的ID和密码而不是auth.User,请帮帮我...
"""
def event_session_required():
def _session_required(view_func):
@wraps(view_func)
def __session_required(request, *args, **kwargs):
next = request.get_full_path()
event_key = kwargs.pop('event_key', '')
session_key = 'event_%s' % event_key
print session_key
login_path = reverse('event-manage-login', args=[event_key])
redirect_url = login_path + '?next=' + next
try:
session = request.session.get(session_key)
if session is None:
raise ValueError('Cannot use None at session value')
except KeyError as e:
messages.error(request, 'session key not found')
return redirect(redirect_url)
except ValueError as e:
messages.error(request, e.message)
return redirect(redirect_url)
else:
if session:
return view_func(request, *args, **kwargs)
else:
return redirect(redirect_url)
return __session_required
return _session_required
"""
def event_session_check(request, event_key):
session_key = 'event_%s' % event_key
if session_key not in request.session or request.session[session_key] != True:
next = request.get_full_path()
next = urlquote_plus(next)
next = iri_to_uri(next)
login_path = reverse('event-manage-login', args=[event_key])
redirect_url = login_path + '?next=' + next
return redirect_url
return None
#@event_session_required
def event_manage(request, event_key):
check_session = event_session_check(request, event_key)
if check_session:
return redirect(check_session)
try:
eventset = EventSet.objects.get(key=event_key)
except EventSet.DoesNotExist:
raise Http404
template = 'event/manage.html'
return render(request, template, {'eventset' : eventset })
#@event_session_required
def event_manage_detail(request, event_key, detail_key:
check_session = event_session_check(request, event_key)
if check_session:
return redirect(check_session)
try:
eventset = EventSet.objects.get(key=event_key)
except EventSet.DoesNotExist:
raise Http404
event_details = eventset.details.all()
template = 'event/manage_detail.html'
return render(request, template, {
'eventset' : eventset,
'event_details': event_details
})
是的!谢谢@V Stoykov和@Aldian Fazrihady,最后我修复了我的代码。现在效果很好。
urls.py:
from django.conf.urls import patterns, url
urlpatterns = patterns('event.views.manage',
url(r'^(?P<event_key>\w+)/login$', 'event_login', name='event-manage-login'),
url(r'^(?P<event_key>\w+)/logout$', 'event_logout', name='event-manage-logout'),
url(r'^(?P<event_key>\w+)/manage$', 'event_manage', name='eventset.manageid '),
url(r'^(?P<event_key>\w+)/edit$', 'event_manage_detail', name='event-manage-detail')
)
decorator.py:
def event_session_required(view_func):
def _session_required(request, *args, **kwargs):
next = request.get_full_path()
event_key = kwargs.get('event_key', '')
login_path = reverse('event-manage-login', args=[event_key])
redirect_url = login_path + '?next=' + next
session_key = 'event_%s' % event_key
try:
session = request.session.get(session_key)
except KeyError:
return redirect(redirect_url)
except ValueError:
return redirect(redirect_url)
else:
if session is None:
del request.session[session_key]
return redirect(redirect_url)
return view_func(request, *args, **kwargs)
return _session_required
manage.py
def event_login(request, event_key):
...
try:
eventset = EventSet.objects.get(key=event_key)
except EventSet.DoesNotExist:
raise Http404
next request.GET.get('next', '')
if request.method == 'POST':
if eventset.manageid == request.POST.get('manageid', '') and eventset.managepwd == request.POST.get('managepwd', '') and eventset.manageid and eventset.managepwd:
......
return redirect(next)
else:
......
...
@event_session_required
def event_manage(request, event_key):
try:
eventset = EventSet.objects.get(key=event_key)
except EventSet.DoesNotExist:
raise Http404
template = 'event/manage.html'
return render(request, template, {'eventset' : eventset })
@event_session_required
def event_manage_detail(request, event_key, detail_key:
try:
eventset = EventSet.objects.get(key=event_key)
except EventSet.DoesNotExist:
raise Http404
event_details = eventset.details.all()
template = 'event/manage_detail.html'
return render(request, template, {
'eventset' : eventset,
'event_details': event_details
})
def event_logout(request, event_key):
session_key = 'event_%s' % event_key
try:
del request.session[session_key]
except:
pass
return redirect(reverse('event-manage', args=[event_key]))
答案 0 :(得分:0)
我看到一个问题和一个可能的问题。
问题是你的装饰者event_session_required
不接受任何参数。相反,真正的装饰者是其中的函数_session_required
。
使用当前代码(如果未注释),如果要装饰函数,则需要调用装饰器。例如:
@event_session_required()
def event_manage(request, event_key):
....
如果您不需要将任何参数传递给event_session_required
,您可以直接接收view_func
并删除_session_required
功能。
def event_session_required(view_func):
@wraps(view_func)
def __session_required(request, *args, **kwargs):
...
@event_session_required
def event_manage(request, event_key):
...
在您的包装视图__session_required
中也存在一个可能的问题。我不知道你如何描述urls.py
中的网址,但从我看到的情况来看,我认为它是位置参数而不是关键字。在__session_required
您期望的关键字。
您有两种选择:
event_session_required
修饰的每个函数都接收event_key
作为第一个位置参数(request
之后),并将__session_required
更改为第一个参数而不是关键字。我会建议No.1
答案 1 :(得分:0)
我从不像event_session_required那样创建最外层的函数。 我总是直接去函数_session_required(view),所以装饰器将是@_session_required。
而不是在kwargs中搜索event_key,而是尝试在args中找到它。