有的网站需求,如果用户未登录,能够进入首页,但当点击想要进入详情页的时候,就会跳转到登录页面,登录完成之后,有的需求需要进入首页;有的需要进入点击登录之前你的意向页面
第一种:登录之后,进入首页。
第二种:登录之后,进入登录之前你点击想进入的意向页面
那么,对于第一种,登录之后,进入首页。Django有一种自带装饰器。比较简单,下面讲解:
在views.py中:
一、如果是普通视图函数:则使用login_required
from django.contrib.auth.views import login_required
@login_required
def add(request):
if request.method == 'GET':
return render(request, './subject/add.html')
elif request.method == 'POST':
try:
name = request.POST.get('name')
amount = request.POST.get('amount')
days = request.POST.get('days')
number = request.POST.get('number')
assurance = request.POST.get('assurance')
remark = request.POST.get('remark')
s = SubjectModel(name=name,amount=amount,days=days,number=number,assurance = assurance,remark=remark,creater_id=request.user.id,updater_id=request.user.id)
s.save()
return redirect('/subject/list')
except:
return render(request,'./subject/add.html',{'result':'学科添加失败!请仔细检查'})
二、如果是通用视图函数,使用method_decorator
from django.utils.decorators import method_decorator
class SubjectAddView(View):
"""
该通用视图是用来展示添加学科的页面subject/add.html,以及处理学科的添加逻辑。
"""
@method_decorator(login_required)
def get(self, request):
return render(request, 'subject/add.html')
@method_decorator(login_required)
def post(self, request):
subject = Subject()
subject.name = request.POST.get('name')
subject.amount = request.POST.get('amount')
subject.days = request.POST.get('days')
subject.number = request.POST.get('number')
# 保存学科之前,先判断学科是否已经存在。
result = Subject.objects.filter(name=subject.name)
if result:
error = {'code': '该学科已存在!'}
# 数据库已经存在该名称的学科
return render(request, 'subject/add.html', locals())
# 保存成功,切换Url,进入/subject/index/首页,展示所添加的学科信息。
# 给学科添加创建人和更新人对应的用户。默认都是当前登录用户。
subject.creater = request.user
subject.updater = request.user
subject.save()
return redirect(reverse('subject_index'))
上面是通用视图函数和普通视图函数的使用装饰器不同,但是有一点,必须要在settings.py中设置:
添加下面一句话:就是制定被装饰函数,如果没用户登录,所要跳转的网址。在这里就是跳转到登录页面
LOGIN_URL = '/user/login/'
下面,讲解第二种,登录之后,进入登录之前你点击想进入的意向页面
这个都需要进行自定义装饰器了,因为在用户没登录的情况下,你要点击首页上的某一个链接进入详情页。要点击的链接都不一样,也就是意向页面不一样。登录之后,要去意向页面。
思路:在首页的时候,你点击某一个链接,想要进入详情页。一、如果用户已登录,直接进入意向页面。二、1.如果没有用户登录,需要自动跳转至登录页面 2.在跳转至登录页面之前,需要将用户所点击的意向页面url地址,保存在cookie中记录下来 3.跳转至登录页面之后,如果用户登录成功,那么就会从cookie取出,在第2步保存到cookie中的意向url地址,进行重定向即可。
在detail的函数中:
def detail(request,article_id):
article = Article.objects.get(id=article_id)
comment_form = CommentForm()
comments = article.comment_set.all()
return render(request,'article_page.html',locals())
在登录login的函数中:
def login_func(request):
if request.method == 'GET':
return render(request,'login.html')
elif request.method == 'POST':
login_form = LoginForm(request.POST)
if login_form.is_valid():
username = login_form.cleaned_data['username']
password = login_form.cleaned_data['password']
user= NewUser.objects.filter(uname=username,upwd=password)
if user:
# 允许登录,保存登录的session信息
request.session['uname'] = username
# 重定向:需要区分用户直接点击的登录页面进行的登录,还是由其他的页面跳转过来的。
# 如果用户直接访问的是登录页面,那么直接跳转到首页。
# 如果是从其他页面跳转过来的,需要获取用户所点击的url地址。比如:用户点击文章标题之后跳转的;用户点击评论之后跳转的;登录之后直接重定向到用户点击的url地址。
user_click_url = request.COOKIES.get('click_url','')
if not user_click_url:
# 说明是用户直接访问的就是登录页面
return redirect(reverse('blog_index'))
else:
# 说明是点击其他链接,跳转过来的。
return redirect(user_click_url)
else:
return render(request,'login.html',{'error':'用户名和密码错误'})
下面,写装饰器:
from django.http import HttpResponseRedirect
def islogin(func_name):
def wrapper(request,*args,**kwargs):
if request.session.get('uname',''):
# 说明当前处于登录状态,直接调用func_name即可
return func_name(request,*args,**kwargs)
else:
# 此时需要获取用户所点击的url,并保存到cookie当中,再跳转到登录页面。
response = HttpResponseRedirect('/blog/login/')
# 用户点击链接,会发送GET请求,对应的request对象中,含有要请求的url地址、请求参数,等等
response.set_cookie('click_url',request.path)
return response
return wrapper
之后,只需要在detail的函数的上面,加上封装好的装饰器即可。
当跳转至登录页面的时候,会看到浏览器中cookie会有保存的click_url的字段
其中,有两个小知识点:
一、进行重定向的时候,
如果url路径中有参数,r’^detail/(?P<article_id>\d+)/$’,如何使用reverse()来反射这个带参数的地址?
下面是解决方案:
return redirect(reverse('blog_detail',args=(article_id,)))
如果url路径中没有参数,但是含有?article_id=1这种请求的参数,如何使用reverse()来反射这个url
下面是解决方案
return redirect(reverse('article'+'?article_id='+article_id))
二、装饰器中使用request.path
用户点击链接,会发送GET请求,对应的request对象中,含有要请求的url地址、请求参数,等等
一、如果url路径中有参数:例如localhost:8000/blog/detail/1/
是在request.path中可以获取,发送请求的网址
二、如果url路径中没有参数,但是含有?article_id=1这种请求的参数。例如:localhost:8000/blog/?article_id=1/ 是在request.get_full_path()中可以获取,发送请求的网址。要不然,使用request.path只会获取到?之前的网站,获取不是完整的