139.用户系统案例

1. 在models.py文件中定义一个用户模型User,示例代码如下:

from django.db import models
<!--导入验证器模块-->
from django.core import validators


class User(models.Model):
    username = models.CharField(max_length=30)
    password = models.CharField(max_length=24)
    <!--自定义验证器,用到了正则表达式-->
    telephone = models.CharField(max_length=11, validators=[validators.RegexValidator(r"1[345678]\d{9}", message={'invalid':'请输入正确的手机号'})])

    class Meta:

        db_table = 'user'

2.实现用户在点击注册的时候可以将用户提交的信息保存到数据库中,如果用户用户输入信息不正确,会让重新用户输入;如果用户已经注册,并且在数据库中已经有了用户注册的信息,就将用户在表单中提交上来的数据与数据库中的数据进行比对,如果找到了就返回首页,并且在浏览器的cookie中记录session_id,其中session_id存储的值就是username。

views.py文件中对用户类视图的定义如下:
from django.shortcuts import render, redirect, reverse
from django.http import HttpResponse
from django.views import View
from .models import User
from .forms import SignupForm,SigninForm


def index(request):
    return render(request, 'static/index.html')


class Signup(View):

    def get(self, request):
        return render(request,'static/signup.html')

    def post(self, request):
        form = SignupForm(request.POST)
        if form.is_valid():
            form.save()
            # 注册完成之后,重定向到首页
            return redirect(reverse('front:index'))
        else:
        <!--如果输入的用户信息不合法,就会让用户重新输入-->
            print(form.errors.get_json_data())
            return redirect(reverse('front:signup'))


class Signin(View):

     def get(self, request):
         form = SigninForm()
         return render(request, 'static/signin.html')

     def post(self, request):
         form = SigninForm(request.POST)
         if form.is_valid():
             # 获取表单中提交的用户信息
             username = form.cleaned_data.get('username')
             password = form.cleaned_data.get('password')
             # 如果可以在数据库中找到具有相同信息的用户,就返回首页
             user = User.objects.filter(username=username, password=password).first()
             if user:
                #  如果用户存在,就在cookie中保存一个session_id,存储的值是用户名,并且返回首页
                request.session['user_id'] = username
                return redirect(reverse('front:index'))
             else:
                 # 如果用户不存在数据库中,就先注册
                 return redirect(reverse('front:signup'))
         else:
             # 如果form表单中提交的信息验证不合法,就打印出相关的错误信息,并且让用户重新登录
             print(form.errors.get_json_data())
             return redirect(reverse('front:signin'))

3.涉及到的表单的定义如下:

from django import forms
from .models import User


<!--注册验证的表单-->
<!--一定要注意的是,这里一定要继承forms.ModelForm-->
class SignupForm(forms.ModelForm):
    password_repeat = forms.CharField(max_length=24)

    class Meta:
        model = User
        fields = '__all__'

<!--因为要对两次输入的密码进行比对,所以可以通过重写类的clean()方法-->
    def clean(self):
        clean_data = super(SignupForm, self).clean()

        password = clean_data.get('password')
        password_repeat = clean_data.get('password_repeat')

        if password != password_repeat:
            raise forms.ValidationError('两次密码输入不一致!')
        else:
            return clean_data


<!--登录验证的表单-->
class SigninForm(forms.ModelForm):

    class Meta:
        model = User
        fields = ['username', 'password')

4.在我们的子urls.py文件中进行视图与url之间的映射,示例代码如下:

from django.urls import path
from . import views
from .views import Signin, Signup

app_name = 'front'


urlpatterns = [
    path('', views.index, name='index'),
    path('signin/', Signin.as_view(), name='signin'),
    path('signup/', Signup.as_view(), name='signup'),
]

5.在我们的父urls.py文件中,与子url进行一层映射,示例代码如下:

from django.urls import path, include

urlpatterns = [
    path('front/', include('front.urls')),
]

自定义上下文处理器:

有时候我们想要返回自己的数据,那么这时候我们可以自定义上下文处理器,自定义上下文处理器步骤如下:

(1)你可以根据这个上下文处理器是属于哪个app,然后在这个app中创建一个文件专门用来存储上下文处理器,比如,context_processor.py,或者是你也可以专门创建一个python包,用来存储所有的上下文处理器。
(2)在你定义的上下文处理器文件中,定义一个函数,这个函数只有一个request参数,这个函数中处理完自己的逻辑后,把需要返回给模板数据,通过字典的形式返回,如果不需要返回任何数据,那么也必须返回一个空的字典。示例代码如下:
from .models import User


def front_user(request):
    user_id = request.session.get('user_id')
    context = {}
    if user_id:
        try:
 # 注意这里一定要使用get()获取用户,返回User object (3),
 # 而不能使用filter()查找是否有用户,返回<QuerySet [<User: User object (3)>]>
            user = User.objects.get(pk=user_id)
            context['front_user'] = user
        except:
            pass
    return context

同时,要在settings.py文件中的TEMPLATES中:OPTIONS中的context_processors添加自定义的处理器的路径,'front.context_processors.front_user',(front APP下的context_processors.py文件中的front_user函数)

posted @ 2020-02-23 22:13  一笑而过~一笑奈何  阅读(108)  评论(0编辑  收藏  举报