- 创建项目创建应用,指定E盘下的django文件夹,创建userProject项目。
-
在命令行下创建项目,django-admin startproject userProject
-
打开userProject文件夹,在项目中创建应用,python manage.py startapp user
-
在“settings.py”文件的“INSTALLED_APPS”中加入user应用。
- 创建模型,在user应用中"models.py"修改代码如下
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.core.exceptions import ValidationError
import re
# Create your models here.
def validate_qq(value):
"""
判断QQ号是否为[5,11]为数字
"""
s=re.match(r"^[1-9]\d{4,10}",value)
if not(s and s.end()==len(value) and len(value)>4):
raise ValidationError('QQ号不正确: %s' % value)
def validate_phone(value):
"""
判断手机号是否正确
"""
s=re.match(r"^1[3458]\d{9}",value)
if not(s and s.end()==len(value) and len(value)==11):
raise ValidationError('手机号不正确:%s' % value)
class myUser(AbstractUser):
qq=models.CharField(max_length=11,verbose_name='QQ号',validators=[validate_qq])
phone=models.CharField(max_length=11,verbose_name='手机号',validators=[validate_phone])
- 在“settings.py”文件“STATIC_URL = '/static/'”后添加如下代码
AUTH_USER_MODEL='user.myUser' #替换默认user模型
- 在命令行中,首先执行进行迁移,python manage.py makemigrations user。执行迁移,python manage.py migrate
- 创建超级用户,python manage.py createsuperuser,输入用户名“admin”,输入密码。
- 创建“templates”文件夹,创建文件“login.html”、“edit_user.html”
- 文件“login.html”
<center>
使用自定义模型实现的用户登录页面
{% if form.errors %}
<p style="color: red">用户名活密码有错,请重新登录!</p>
{% endif %}
<form method="POST" action="{% url 'login' %}">
{% csrf_token %}
<table>
<tr>
<td align="right">用户名:</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td align="right">密码:</td>
<td>{{ form.password }}</td>
</tr>
</table>
<input type="submit" value="登录">
<input type="hidden" name="next" value="{% url 'change_user' %}">
<p><a href="{% url 'add_new' %}">新用户注册</a></p>
</form>
</center>
- 文件“edit_user.html”
<style>
.error{
color: red
}
</style>
{{title|safe}}<hr>
<form action="" method="POST">
{% csrf_token %}
<table>
{{form}}
<tr>
<td colspan="3">
<input type="submit" value="提交" id="submit">
</td>
</tr>
</table>
</form>
<hr>
<span style="color: red">{{msg|safe}}</span>
- 文件“urls.py”
"""userProject URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.contrib.auth import views as auth_views
from user import views as user_views
urlpatterns = [
path('admin/', admin.site.urls),
path('login/',auth_views.LoginView.as_view(template_name='login.html'),name='login'),
path('add/',user_views.add_new,name='add_new'),
path('change/',user_views.change_user,name='change_user'),
]
- 文件“views.py”
from django.db.models import fields
from django.shortcuts import redirect, render
from django.forms import ModelForm
from .models import myUser
from django.urls import reverse
# Create your views here.
class myUserForm(ModelForm):
#定义模型表单,用于处理myUser模型
class Meta:
model=myUser
fields=['username','password','email','qq','phone']
lables={'username':'用户名','password':'密码','email':'Email'}#其他字段用morenlabel
from django.forms.utils import ErrorList
class myErrorList(ErrorList):#自定义错误列表格式
def __str__(self):
return self.todivs()
def todivs(self):
if not self:return ''
return '<div class="errorlist">%s</div>' % ''.join(['<div class="error">%s</div>' % e for e in self])
def add_new(request):#处理添加新用户
msg=''
if request.method=='POST':#在用户提交新用户数据时,用数据创建模型表单
mform=myUserForm(request.POST,auto_id=False,error_class=myErrorList)
if mform.is_valid():
#在表单通过验证时执行数据处理
user_name=mform.cleaned_data['username']
password=mform.cleaned_data['password']
u=myUser.objects.filter(username=user_name)#用表单数据查询
mform.save() #将数据存入数据库
#保存模型表单时,密码已明文的方式存入password字段,应通过set_password()方法设置密码
u=myUser.objects.get(username=user_name) #用表单数据查询
u.set_password(password) #正确处理密码字段
u.save() #保存对密码的修改
msg='数据已保存'
else:
msg='数据有错,请修改后重新提交'
else:
mform=myUserForm() #创建空白表单
msg='请输入数据添加注册新用户!'
title='新用户注册,<a href="%s">登录</a>'%reverse('login')
return render(request,'edit_user.html',{'form':mform,'msg':msg,'title':title})
from django.contrib.auth.decorators import login_required
@login_required #必须登录后才能修改个人数据
def change_user(request): #处理修改用户数据
if request.method=='POST':
name_ok=False
#提交表单时采用POST方法,用提交的数据修改当前用户
mform=myUserForm(request.POST,auto_id=False,error_class=myErrorList)#创建表单
data_ok=mform.is_valid() #执行表单验证,检查数据是否正确
user_name=request.POST.get('username') #获得提交的用户名
if not data_ok:
#在没有修改用户名时,模型表单会报错,认为已存在的相同的用户名
#此时也应使用提交的数据修改用户,下面的语句用于检测这种情况
error_msg='username already exists'
username_error='%s'%mform.errors.get('username')
if username_error.find(error_msg)>-1 and user_name==request.user.username:
name_ok=True #在未修改用户名时,忽略表单报告的用户名重复错误
#else:
# name_ok=False
if data_ok or (name_ok and not data_ok):#数据同规格校验时,用其修改当前用户
u=myUser.objects.get(username=request.user.username)#获得要修改的模型对象
#本例中将修改和未修改用户名统一处理,所以在此更改了用户名
u.username=user_name
u.set_password(request.POST.get('password')) #注意密码字段的修改方式
u.email=request.POST.get('email')
u.qq=request.POST.get('qq')
u.phton=request.POST.get('phone')
u.save() #将模型对象数据写入数据库
return redirect(reverse('login')) #完成数据修改后,重定向到登录页面
else:
msg='数据有错,请修改后重新提交!'
else:
#请求方法不是POST,说明是通过URL请求,
#此时用request中的已登录用户数据创建表单
username=request.user.username
email=request.user.email
qq=request.user.qq
phone=request.user.phone
data={'username':username,'password':'','email':email,'qq':qq,'phone':phone}
mform=myUserForm(data,auto_id=False,error_class=myErrorList)#创建表单
mform.errors.clear()#表单会报告已存在同名用户错误,所以在此清楚错误信息
msg='修改当前用户数据'
title='修改用户数据,当前用户名:%s,<a href="%s">登录</a>' %(request.user.username,reverse('login'))
return render(request,'edit_user.html',{'form':mform,'msg':msg,'title':title})