Django2 Web 实战02-用户注册登录退出

作者:Hubery 时间:2018.9.14

接上文:Django2 Web实战01-启动项目-model 扩展

上一节中,我们创建了工程,且创建了core应用以及core的相关models(Movie,Person)。 接下来我们在这基础上继续完善:

  • 用户注册/登陆/登出

1. 创建user应用

这里,创建一个新的Django app:user,将其注册到工程里,用来管理用户。 我们尽量那个让user app复用。

1.1 创建一个Django的app

命令行创建user

cd MyMovie
python manage.py startapp user
复制代码

注册到Django工程里 MyMovie/settings.py

INSTALLED_APPS = [
    'user',  # 必须在admin之前
    'core',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
复制代码

注: 将我们的app放到Django自带的app之前注册,是个好习惯。 Django的内建app:auth,为我们提供了一个可用的user模型。

1.2 创建一个注册视图

创建视图之前,先创建一个自定义的表单:UserForm,包含几个注册内容:username/first_name/last_name/password/email,这应该算是一个用户最基本的信息了; 好 user/forms.py,如果没有forms.py文件,就地创建:

from django import forms
from django.contrib.auth.models import User

class UserForm(forms.ModelForm):
    username = forms.CharField(widget=forms.TextInput({
                'class': 'form-control',
                'placeholder': '请输入用户名'}))
    first_name = forms.CharField(widget=forms.TextInput({
            'class': 'form-control',
            'placeholder': '请输入名字'}))
    last_name = forms.CharField(widget=forms.TextInput({
            'class': 'form-control',
            'placeholder': '请输入姓氏'}))
    password = forms.CharField(widget=forms.PasswordInput({
            'class': 'form-control',
            'placeholder': '请输入密码'}))
    email = forms.CharField(widget=forms.TextInput({
            'class': 'form-control',
            'placeholder': '请输入邮箱'}))

    class Meta:
        model = User
        fields = ('username',
                  'first_name',
                  'last_name',
                  'email',
                  'password')
复制代码

RegisterView类可以让用户在我们的网站上注册。重写get post函数,处理注册成功/失败的情况。 user/views.py

from django.contrib.auth.models import User
from django.shortcuts import render
from django.views.generic import View
from user.forms import UserForm

# 注册视图
class RegisterView(View):
    form_class = UserForm  # 上文自定义的表单
    template_name = 'user/register.html'

    # 显示空表单
    def get(self, request):
        form = self.form_class(None)
        return render(request, self.template_name, {'form': form})

    # 处理POST表单数据
    def post(self, request):
        form = self.form_class(request.POST)
        if form.is_valid():
            user = User.objects.create_user(
                username=form.cleaned_data['username'],
                first_name=form.cleaned_data['first_name'],
                last_name=form.cleaned_data['last_name'],
                email=form.cleaned_data['email'],
                password=form.cleaned_data['password'],
            )
            # 保存到数据库中
            user.save()
            # 注册成功之后 跳转到成功页面
            return render(request, 'user/register_success.html', {'form': form})
        return render(request, self.template_name, {'form': form})
复制代码
  • RegisterView继承了View,需要重写GET/POST方法。

  • template_name = 'user/register.html',这是将要创建的模版。它的context与之前见过的稍微有些不同;它没有objectobject_list变量,但有个form变量,这个变量是一个类实例,我们在form_class属性中设置的。

  • form_class = UserForm,这就是View要用的form类。简单的模型可以直接设置model = MyModel,但一个user模型比较复杂,不能直接这么设置。这个问题可以后续详述。

  • 如果View接收到一个GET请求,它会给form渲染一个空模版。

  • 如果View接收到一个POST请求,同样会通过self.form_class(request.POST)来创建form实例。如果该form有效:form.is_valid(),则根据form中用户输入的数据来创建用户,并保存到数据库中,同时渲染出创建成功的模版。

1.3 创建注册视图对应的模版

写模版前我们要知道,Django没有提供

或者 {% endblock %} 复制代码

user/templates/user/register_success.html

{% extends 'base.html' %}
{% block main %}
    
'create-account-msg-container'>
'circle'> "fa fa-thumbs-o-up" aria-hidden="true">

账户已成功注册!

"{% url 'user:login' %}">点击登陆
{% endblock %} 复制代码

这两个模版与之前的模版一样,继承base.html,将代码写在已经存在的block中。 当一个模版渲染出来,将被渲染成两部分,第一部分是可选的tag,

    用来生成错误信息,然后每个字段都被渲染成4个基本的部分:

      • tag 显示用户之前提交的错误信息,只有出错的时候才会显示
      • 或者