看啥推荐读物
专栏名称: GHope
比起鲜衣怒马的牵黄擎苍啊,我还是更喜欢白衣策马的仗剑天涯。
今天看啥  ›  专栏  ›  GHope

Django中自定义注册登录注销实现

GHope  · 简书  ·  · 2018-10-01 20:07
项目结构

基本步骤

激活虚拟环境

进入到安装虚拟环境Scripts文件夹中,执行activate激活环境(deactivate退出环境)

创建工程

django-admin start

创建项目

python manage.py startapp users

修改配置文件

添加创建的项目到工程

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'users',
]

销毁冲突的中间件

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'utils.UserAuthMiddleware.UserMiddleware',
]

加载模型

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

连接数据库

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django1',
        'USER': 'root',
        'PASSWORD': 'root',
        'HOST': '127.0.0.1',
        'PORT': 3306,

    }
}

配置static访问路径

STATICFILES_DIRS = [
    os.path.join(BASE_DIR,'static')
]

建立模块并完成数据迁移

建立模块

from django.db import models


class Users(models.Model):
    username = models.CharField(max_length=10, unique=True, verbose_name='姓名')
    password = models.CharField(max_length=520, verbose_name='密码')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    operate_time = models.DateTimeField(auto_now=True, verbose_name='修改时间')

    class Meta:
        db_table = 'users'


class UserTicket(models.Model):
    user = models.ForeignKey(Users)
    ticket = models.CharField(max_length=30)
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

    class Meta:
        db_table = 'user_ticket'

生成迁移文件
python manage.py makemigrations
迁移数据
python manage.py migrate

路由设置

与工程同名项目下创建路由及命名空间

from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^users/', include('users.urls',namespace='users')),
]

创建的项目中穿件urls.py,并创建相关路由

from django.conf.urls import url

from users import views

urlpatterns = [
    # 注册
    url(r'^register/', views.register, name='register'),
    # 登录
    url(r'^login/', views.login, name='login'),
    # 首页
    url(r'^index/', views.index, name='index'),
    # 注销
    url(r'^logout/', views.logout, name='logout'),

]

模板内容

父模板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>
        {% block title %}{% endblock %}
    </title>
    {% block css %}{% endblock %}
    {% block js %}{% endblock %}
</head>
<body>
    {% block content %}{% endblock %}
</body>
</html>

注册页面

{% extends 'base.html' %}

{% block title %}
    注册页面
{% endblock %}

{% block content %}
<form action="" method="post">
    <p>姓名:<input type="text" name="username"></p>
    <p>密码:<input type="password" name="password"></p>
    <input type="submit" value="注册">
</form>
{% endblock %}

登录界面

{% extends 'base.html' %}

{% block title %}
    登录页面
{% endblock %}

{% block content %}
    <form action="" method="post">
        <p>姓名:<input type="text" name="username"></p>
        <p>密码:<input type="password" name="password"></p>
        <input type="submit" value="登录">
    </form>
{% endblock %}

测试登录成的界面

<p>登录成功,进入首页</p>
<p>{{ user.username }}</p>
<a href="{% url 'users:logout' %}">注销</a>

逻辑实现

from django.contrib.auth.hashers import make_password, check_password
from django.shortcuts import render
from django.http import HttpResponseRedirect, HttpResponse
from django.urls import reverse

from users.forms import UserForm
from users.models import Users, UserTicket
from utils.functions import get_ticket, is_login


def register(request):
    if request.method == 'GET':
        # 如果请求为get,则返回注册页面
        return render(request, 'register.html')

    if request.method == 'POST':
        # 校验参数
        form = UserForm(request.POST)

        # 判断校验是否成功(is_valid()为真即为校验成功)
        if form.is_valid():
            # 注册
            password = make_password(form.cleaned_data['password'])
            Users.objects.create(username=form.cleaned_data['username'],
                                 password=password)
            # 跳转到登录页面,使用namespace:name
            return HttpResponseRedirect(reverse('users:login'))

        else:
            return render(request, 'register.html')


def login(request):
    if request.method == 'GET':
        return render(request, 'login.html')

    if request.method == 'POST':
        # 校验登录界面的参数
        form = UserForm(request.POST)
        # 使用is_valid()判断是否校验成功
        if form.is_valid():
            # 登录的设置
            # 1、通过用户名和密码获取当前的user对象 --> auth.authenticate
            user = Users.objects.filter(username=form.cleaned_data['username']).first()
            if user:
                # 获取到user对象
                if check_password(form.cleaned_data['password'], user.password):
                    # 校验成功
                    # 1、向cookie中设置随机参数ticket
                    res = HttpResponseRedirect(reverse('users:index'))
                    ticket = get_ticket()
                    # res.set_cookie(key, value='', max_age=None, expires=None)
                    res.set_cookie('ticket', ticket, max_age=1000)
                    # 2、向user_ticket中存入这个ticket和user的对应关系
                    UserTicket.objects.create(user=user, ticket=ticket)
                    return res
                else:
                    # 密码错误
                    return render(request, 'login.html')
            else:
                # 用户不存在
                return render(request, 'login.html')
            # 2、设置cookie中的随机值  --> auth.login()
            # 3、设置user_ticket中的随机值
            pass
        else:
            return render(request, 'login.html')


# @is_login
def index(request):
    if request.method == 'GET':
        # 获取ticket
        # ticket = request.COOKIES.get('ticket')
        # # 通过ticket去user_ticket表中取数据
        # user_ticket = UserTicket.objects.filter(ticket=ticket).first()
        # if user_ticket:
        #     # 获取当前用户
        #     user = user_ticket.user
        #     return render(request, 'index.html', {'user': user})
        # else:
        #     return HttpResponseRedirect(reverse('users:login'))

        return render(request, 'index.html')


def logout(request):
    if request.method == 'GET':
        ticket = request.COOKIES.get('ticket')
        user_ticket = UserTicket.objects.filter(ticket=ticket).first()
        if user_ticket:
            user_ticket.delete()
        return HttpResponseRedirect(reverse('user:login'))

为cookie设置随机值

import random


def get_ticket():
    s = '1234567890qwertyuiopasdfghjklzxcbnvm'
    ticket = ''
    for i in range(25):
        ticket += random.choice(s)

    return ticket



原文地址:访问原文地址
快照地址: 访问文章快照