对于一个网站来说,比较好的用户体验是登录、注册和注销后跳转回用户之前访问的页面。
在登录和注销的视图函数中,Django 已经为我们处理了跳转回用户之前访问页面的流程。
其实现的原理是,在登录和注销的流程中,始终传递一个 next 参数记录用户之前访问页面的 URL。
我们需要做的就是在用户访问登录或者注销的页面时,在 URL 中传递一个 next 参数给视图函数,具体做法如下:
<li class="cl-effect-11"><a href="{% url 'logout' %}" data-hover="退出">退出</a></li> {% else %} <li class="cl-effect-11"><a href="{% url 'login' %}" data-hover="登陆">登陆</a></li> <li class="cl-effect-11"><a href="{% url 'users:register' %}?next={{ request.path }}" data-hover="注册">注册</a></li> {% endif %}
可以看到,我们在登录和注销的 URL 后加了 next 参数,其值为 {{ request.path }}。request.path 是用户当前访问页面的 URL。
为了在整个登录流程中记录 next 的值,还需要在登录表单中增加一个表单控件,用于传递 next 值。
<form class="form" action="{% url 'users:register' %}" method="post" enctype="multipart/form-data"> {% csrf_token %} {% for field in form %} {{ field.label_tag }} {{ field }} {{ field.errors }} {% if field.help_text %} <p class="help text-small text-muted">{{ field.help_text|safe }}</p> {% endif %} {% endfor %} {# {{ form | crispy }}#} <button type="submit" class="btn btn-primary btn-block">注册</button> <input type="hidden" name="next" value="{{ next }}"/> </form>
即在表单中增加了一个隐藏的 input 控件,其值为 {{ next }},即之前通过 URL 参数传递给登录视图函数的,然后登录视图函数又将该值传递给了 login.html 模板。
这样在整个登录流程中,始终有一个记录着用户在登录前页面 URL 的变量 next 在视图和模板间来回传递,直到用户登录成功后再跳转回 next 记录的页面。
类似的,我们也希望用户注册后返回注册前页面。
不过由于注册视图函数是我们自己写的,所以需要我们自己去获取跳转的地址。
需要修改一下注册视图函数:
def register(request): # 拿到next redirect_to = request.POST.get('next', request.GET.get('next', '')) # 判断是什么方式提交的 if request.method == 'POST': form = registerForm(request.POST, request.FILES) if form.is_valid(): user = form.save() messages.success(request, '注册成功!') if redirect_to: # 注册完直接登陆 login(request, user) return redirect(redirect_to) else: return redirect(reverse('login')) else: form = registerForm() return render(request, 'users/register.html', {'form': form, 'next': redirect_to})
-------------------------------------------------------------------------------------------------------------------------------------------
如果想要注册后直接登陆成功
from django.contrib.auth import login
def register(request):
# 拿到next
redirect_to = request.POST.get('next', request.GET.get('next', ''))
# 判断是什么方式提交的
if request.method == 'POST':
form = registerForm(request.POST, request.FILES)
if form.is_valid():
user = form.save()
messages.success(request, '注册成功!')
if redirect_to:
login(request, user)
return redirect(redirect_to)
else:
return redirect(reverse('login'))
else:
form = registerForm()
return render(request, 'users/register.html', {'form': form, 'next': redirect_to})