代码改变世界

128-django的注册和登录【2】:注册和登录的初步实现

2020-08-27 18:44  lzhshn  阅读(175)  评论(0编辑  收藏  举报

注册和登录是两个流程。

因为主要利用了预设的user类,登录比较简单,只要有用户名和密码即可;而注册会比较麻烦一点,你的网站的用户信息通常会大于django默认设置的user类,因此需要对user类进行拓展:

一种方式是自己创建一个user类(比如MyUser),继承默认的User,然后设置这个MyUser,最后用MyUser替代官方默认的User;

另一种方式是建立一个和User是1v1对应关系的新类,增添一些属性。

 

先看登录流程:

 

【1】由于直接使用预设的user类,所以不需要模型,而直接在表单类中指明其承载user类即可。

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


# 仅作测试用,非正常情况
class UserLoginForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['username', 'password']
        labels = {'username': '用户名称', 'password': '用户密码'}

  

 

【2】在视图中,直接使用了authenticate方法,他获得一组username-password,然后去和数据库里进行匹配,并返回一个user(或空),然后根据返回,即可判断登录是否成功!

注意:这里不能忘记了对user的引用:from django.contrib.auth.models import User,在pycharm中,引用后这行代码是灰色的,但是其实不可或缺。

如果没有引用,username=username等式的左侧就不知道是什么了!

from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect, HttpResponse
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
from .models import ExUser
from .forms import UserLoginForm, UserRegForm


def login(request):
    if request.method != 'POST':
        form = UserLoginForm
        context = {'form': form}
        return render(request, 'login.html', context)
    else:
        username = request.POST['username']
        password = request.POST['password']
        login_user = authenticate(request, username=username, password=password)
        if login_user is not None:
            return HttpResponse('login ok!')
        else:
            return HttpResponse('login wrong!')

  

 

【3】模板非常简单,没啥可说的!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>login</title>
</head>
<body>
    <form action="{% url 'account:login' %}" method="post">
        {% csrf_token %}
        {{form.as_p}}
        <input type="submit" value="login" />
    </form>
</body>
</html>

  

 

再看注册流程:

 

【1】按前面所说,注册时需要拓展user类,这里使用一个最常见也最必须的拓展:密码确认。

这个类只有一个属性confirm_password,并使用OneToOneField和预设的user类绑定1对1关系。

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


# Create your models here.
class ExUser(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    confirm_password = models.CharField(max_length=256)

  

 

【2】由于完成注册涉及到2个模型,因此使用ModelForm来创建表单已经不可能,只能完全自定义一个表单。

使用PasswordInput会在输入时,用圆点代替字符,不过这仅仅只是前端表现,此时并没有真正加密。

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



# 不依赖于ModelForm,完全自定义的一个form类
class UserRegForm(forms.Form):
    username = forms.CharField(max_length=128, label='用户名称')
    password = forms.CharField(max_length=256, label='用户密码', widget=forms.PasswordInput)
    confirm_password = forms.CharField(max_length=256, label='确认密码', widget=forms.PasswordInput)
    email = forms.EmailField(label='电子邮箱')

  

 

【3】视图里对注册的处理略微复杂,我们关注else部分即可:

在使用form接收表单传来的数据之后,如果验证有效,可使用form.cleaned_data[ ]的方法,将一些值取出来。使用x=form.save(commit=False),然后通过x去取值也许也可以,但不确定?

最重要的一步是:User.objects.create_user(),通过这个方法可以用传来的值创建一个用户,并且自动完成保存。

当这个user对象保存之后,接下来就是用关联关系,让exuser对应起来,并且存储他自己的属性。虽然这里保存一个confirm_password看起来没有多大意义,不过如果保存的手机号,地址,QQ等,就会很有意义。

  

from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect, HttpResponse
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
from .models import ExUser
from .forms import UserLoginForm, UserRegForm



def register(request):
    if request.method != 'POST':
        form = UserRegForm
        context = {'form': form}
        return render(request, 'reg.html', context)
    else:
        form = UserRegForm(request.POST)
        if form.is_valid():
            # return HttpResponse('ok!')

            username = form.cleaned_data['username']
            password = form.cleaned_data['password']
            email = form.cleaned_data['email']
            confirm_password = form.cleaned_data['confirm_password']
            if password == confirm_password:
                new_user = User.objects.create_user(username=username, password=password, email=email)
                new_exuser = ExUser(user=new_user)
                new_exuser.confirm_password = confirm_password
                new_exuser.save()
                return HttpResponse('ok!')
            else:
                pass
        else:
            pass

  

 

【4】最后就是模板部分,同样很简单,没啥可说的!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>register</title>
</head>
<body>
    <form action="{% url 'account:register' %}" method="post">
        {% csrf_token %}
        {{form.as_p}}
        <input type="submit" value="register" />
    </form>
</body>
</html>