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函数)
始于才华,忠于颜值;每件事情在成功之前,看起来都是天方夜谭。一无所有,就是无所不能。