使用Django搭建博客第二天笔记--登录注册功能实现

一、数据表结构设计
项目应用account的模型MyUser是项目中的核心数据,它与每个项目应用的模型都存在数据关联。模型MyUser继承内置模型User,在内置模型User的基础上添加新的字段,用于完善用户信息。打开项目应用account的models.py定义模型MyUser,代码如下:

class MyUser(AbstractUser):
    name = models.CharField(verbose_name="姓名",max_length=50,default='匿名用户')
    introduce = models.TextField(verbose_name='简介',default="暂无介绍")
    company = models.CharField(verbose_name="公司",max_length=100,default='暂无信息')
    profession = models.CharField(verbose_name='职业',max_length=100,default='暂无信息')
    address = models.CharField(verbose_name='地址', max_length=100, default='暂无信息')
    telephone = models.CharField(verbose_name='电话', max_length=11, default='暂无信息')
    wx = models.CharField(verbose_name='微信', max_length=50, default='暂无信息')
    qq = models.CharField(verbose_name='qq',max_length=50,default='暂无信息')
    wb = models.CharField(verbose_name='微博', max_length=100, default='暂无信息')
    photo = models.ImageField(verbose_name='头像', blank=True,upload_to='images/user/')
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)

    class Meta:
        verbose_name = '用户'
        verbose_name_plural = verbose_name
        db_table = 'MyUser'

    def __str__(self):
        return self.name

二、路由定义
采用路由下发的方式,我们在Myblog的urls.py下设置account的路由

#  Myblog的 urls.py
urlpatterns = [
    path('admin/', admin.site.urls),
    path('user/', include('app.account.urls')),
]
# account的 urls.py
urlpatterns = [
    path('register', Register.as_view(), name="register"),
    path('login', UserLogin.as_view(), name="userLogin"),
]

三、编写视图类
我们在account创建一个一个forms.py用来创建UserForm类,用来进行表单认证:

from django import forms
from django.forms import Form
from app.account.models import MyUser
from captcha.fields import CaptchaField

class UserForm(Form):
    username = forms.CharField(
        widget=forms.TextInput
    )
    password = forms.CharField(
        widget=forms.PasswordInput
    )
    cp = forms.CharField(
        widget=forms.PasswordInput,
        required=False
    )
    type = forms.CharField(
        widget=forms.TextInput
    )
    captcha = CaptchaField()

    def clean(self):
        username = self.cleaned_data.get("username", '')

        if self.cleaned_data.get("type", '') == 'register':
            if not username:
                raise forms.ValidationError("用户名不能为空")
            else:
                user = MyUser.objects.filter(username=username).exists()
                if user:
                    raise forms.ValidationError("用户名已存在")

            p = self.cleaned_data.get("password", '')
            cp = self.cleaned_data.get("cp", '')

            if p != cp:
                raise forms.ValidationError("两次密码不一致")

            else:
                d = {
                    'username': username,
                    'password': p,
                    'is_superuser': 1,
                    'is_staff': 1
                }
                user = MyUser.objects.create_user(**d)# create_user自动将明文密码hash加密
                user.save()
        else:
            if not username:
                raise forms.ValidationError("用户名不能为空")

在account的view.py添加如下代码

from django.shortcuts import render, redirect, reverse
from django.views.generic import View
from .forms import *
from django.contrib.auth import authenticate, login
from captcha.models import CaptchaStore
from captcha.helpers import captcha_image_url


class Register(View):
    info = {
        'title': '注册博客',
        'pageTitle': '用户注册',
        "confirmPassword": True,
        'button': '注册',
        "urlText": '用户登录',
        "submitUrl": 'register',
        "urlName": 'userLogin',
        "tips": '',
        'form': '',
    }

    def get(self, request):
        self.info['form'] = UserForm()
        return render(request, 'user.html', self.info)

    def post(self, request):
        user_from = UserForm(request.POST)

        if user_from.is_valid():
            self.info["tips"] = '注册成功,请登录'
            return redirect(reverse("register"), self.info)
        else:
            self.info["tips"] = user_from.errors.as_data().values()
            return render(request, 'user.html', self.info)


class UserLogin(View):
    info = {
        'title': '登录博客',
        'pageTitle': '用户登录',
        'button': '登录',
        'urlText': '用户注册',
        'urlName': 'register',
        'submitUrl': 'userLogin',
        'tips': '',
        'form': '',
        'new_key': '',
        'image_url': ''
    }

    def get(self, request):
        self.info['new_key'] = CaptchaStore.pick()  # 生成hashkey
        self.info['image_url'] = captcha_image_url(self.info['new_key'])  # 生成验证码图片url地址

        self.info['form'] = UserForm()
        return render(request, 'user.html', self.info)

    def post(self, request):
        user_from = UserForm(request.POST)

        # 表单验证
        if user_from.is_valid():

            username = user_from.cleaned_data.get("username", '')
            password = user_from.cleaned_data.get("password", '')

            if not username or not password:
                self.info['tips'] = "用户名或密码不能为空"
                return render(request, 'user.html', self.info)

            else:
                if MyUser.objects.filter(username=username).exists():
                    user = authenticate(username=username, password=password)
                    if user:
                        if user.is_active:
                            '''
                            
                            '''
                            login(request, user)
                            return redirect(reverse("index"), self.info)
                    else:
                        self.info['tips'] = '密码错误'
                        return render(request, 'user.html', self.info)
                else:
                    self.info['tips'] = '用戶不存在'
                    return render(request, 'user.html', self.info)
        else:
            self.info["tips"] = user_from.errors.as_data().values()
            return render(request, 'user.html', locals())

四、jinja2模板引擎
更换django自带的模板引擎,采用jinja2模板引擎,在Myblog的setting中,在TEMPLATES配置中设置jinja2,用Myblog创建jinja2.py添加jinja2环境

# Myblog的setting中
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.jinja2.Jinja2',
        'DIRS': [os.path.join(BASE_DIR, 'templates')]
        ,
        'APP_DIRS': True,
        'OPTIONS': {
            'environment': 'Myblog.jinja2.environment',
        },
    },
    {
        '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',
            ],
        },
    },
]
#  jinja2.py
from django.contrib.staticfiles.storage import staticfiles_storage
from django.urls import reverse
from jinja2 import Environment


# 将jinja2 模板设置到项目环境中
def environment(**options):
    env = Environment(**options)
    env.globals.update({
        'static': staticfiles_storage.url,
        'url': reverse,
    })
    return env

五、模板编写
jinja2模板引擎编写,跟django自带的模板用法类似




	{{ title }}
	
	
    
    


六、验证码

七、效果图
使用Django搭建博客第二天笔记--登录注册功能实现_第1张图片

你可能感兴趣的:(python,学习笔记,django,python)