1 准备工作
1.1 环境搭建
1.1.1 安装python3.6
python安装官网
1.1.2 安装django2.2
pip install django(==2.2.0) //不加版本默认安装最新
1.1.3 安装pycharm(社区版,官网下载安装即可)
在安装完成后要配置好需要的第三方库:(pip下载,推荐在pycharm下也配置虚拟环境)
Django2.2
连接mysql需要的库:PyMySQL, mysql, mysqlclinet
验证码用到的库:django-simple-captcha(只需在虚拟环境下配置)
(由于下载库较多,忘记用到的库,下附截图)

1.1.4 安装数据库,我使用的是MySQL,推荐安装界面管理文件(我使用的是MySQLWorkbench)
数据库配置,settings.py文件
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME':'cet', #数据库名字'USER':'root', #登陆数据库的用户名'PASSWORD':'123', #登陆数据库的密码'HOST':'localhost', #数据库的ip地址'PORT':'3306', #ip地址的端口号,默认(3306)}}
__init__.py里面导入pymysql
import pymysqlpymysql.install_as_MySQLdb()
1.2 创建django项目及app
1.2.1 创建指令
django-admin startproject project_name #创建项目python manage.py startapp app_name #创建app(可能会报错)#上面创建app失败用下面这个指令django-admin startapp app_name
1.2.2 注册app
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'login', #登录注册
'captcha', #验证码
'home', #报名主页
]
1.4 更改时区和语言
settings.py文件中,将默认改为亚洲/上海和中文
LANGUAGE_CODE = 'zh-hans'TIME_ZONE = 'Asia/Shanghai'USE_I18N = TrueUSE_L10N = TrueUSE_TZ = False
1.5 数据库迁移
更改models.py后,要将更改同步到数据库之中,这时就要用到数据库迁移指令(若迁移失败:no changes问题)。
python manage.py makemigrationspython manage.py migrate
1.6 创建超级管理员
命令行冲使用指令创建管理员账号用于使用django自带的框架。
python manage.py createsuperuser
1.7 运行准备
添加端口号:

2 注册登录模块
(我将其放在了app名为login里面)
2.1 数据库模型设计
特殊参数说明:verbose_name——用于修改django框架各表成员的名字(相当于副名,只用于显示),其他可以从文章开头推荐的博客了解。
#login/models.py
from django.db import models
# Create your models here.
class User(models.Model):
'''用户表'''
gender = (
('male', '男'),
('female', '女'),
)
name = models.CharField(verbose_name="用户名", max_length=128, unique=True) # unique表示唯一
password = models.CharField(verbose_name="密码", max_length=256)
email = models.EmailField(verbose_name="邮箱", unique=True)
sex = models.CharField(verbose_name="性别", max_length=32, choices=gender, default='男')
c_time = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
#用于将django自带管理员端汉化
class Meta:
ordering = ['c_time']
verbose_name = '用户'
verbose_name_plural = '用户'
2.2 在admin中注册模型
#login/admin.pyfrom django.contrib import admin# Register your models here.from . import modelsadmin.site.register(models.User)
2.3 创建表单
在我们创建数据库用户表后,采用表单验证前端的数据并进行存储到数据库中。
#login/forms.pyfrom django import formsfrom captcha.fields import CaptchaFieldclass user_entry(forms.Form):user_name = forms.CharField(label="用户名", max_length=128, widget=forms.TextInput(attrs={'class': 'form-control'}))user_true_name = forms.CharField(label="真实姓名", max_length=128,widget=forms.TextInput(attrs={'class': 'form-control'}))user_id = forms.CharField(label="身份证号", max_length=18, widget=forms.TextInput(attrs={'class': 'form-control'}))email = forms.EmailField(label="邮箱地址", widget=forms.EmailInput(attrs={'class': 'form-control'}))exam_point = forms.CharField(label="考点", max_length=128, widget=forms.TextInput(attrs={'class': 'form-control'}))class user_datas(forms.Form):email = forms.EmailField(label="邮箱地址", widget=forms.EmailInput(attrs={'class': 'form-control'}))user_name = forms.CharField(label="用户名", max_length=128, widget=forms.TextInput(attrs={'class': 'form-control'}))user_true_name = forms.CharField(label="真实姓名", max_length=128, widget=forms.TextInput(attrs={'class': 'form-control'}))user_id = forms.CharField(label="身份证号", max_length=18, widget=forms.TextInput(attrs={'class': 'form-control'}))# user_img =user_school = forms.CharField(label="所在学校", max_length=128, widget=forms.TextInput(attrs={'class': 'form-control'}))# user_f_score = forms.CharField(label="四级成绩", max_length=10, widget=forms.TextInput(attrs={'class': 'form-control'}))# user_s_score = forms.CharField(label="六级成绩", max_length=10, widget=forms.TextInput(attrs={'class': 'form-control'}))
2.4 路由及视图设计
2.4.1 路由设计
由于登陆注册使用的路径不多,就将其全放在项目目录下的urls.py文件,当然也可以采用项目和app相结合。
#项目名/urls.pyfrom django.contrib import adminfrom django.urls import path,includefrom login import viewsurlpatterns = [path('', views.index), #修改端口默认主页path('admin/', admin.site.urls), #管理员端#登录注册path('index/', views.index),path('check/', views.check),path('login/', views.login),path('register/', views.register),path('logout/', views.logout),#使用验证码path('captcha', include('captcha.urls')),#报名app路由path('homepage/',include('home.urls')),]
2.4.2 视图设计
#login/views.pyfrom django.shortcuts import render, redirectfrom . import modelsfrom .forms import UserForm,RegisterFormfrom home.models import user_data# Create your views here.def check(request):passreturn render(request, 'login/hello.html')def index(request):passreturn render(request, 'login/index.html')#加入sessondef login(request):#不允许重复登录if request.session.get('is_login', None):return redirect('/index')if request.method == "POST":login_form = UserForm(request.POST)message = "请检查填写的内容!"if login_form.is_valid():username = login_form.cleaned_data['username']password = login_form.cleaned_data['password']try:user = models.User.objects.get(name=username)if user.password == password:#往session字典内写入用户状态和数据request.session['is_login'] = Truerequest.session['user_id'] = user.idrequest.session['user_name'] = user.namereturn redirect('/index/')else:message = "密码不正确!"except:message = "用户不存在!"return render(request, 'login/login.html', locals())login_form = UserForm()return render(request, 'login/login.html', locals())def logout(request):if not request.session.get('is_login', None):# 如果本来就未登录,也就没有登出一说return redirect("/index/")request.session.flush()# 或者使用下面的方法# del request.session['is_login']# del request.session['user_id']# del request.session['user_name']return redirect("/index/")def register(request):if request.session.get('is_login', None):# 登录状态不允许注册。return redirect("/index/")if request.method == "POST":register_form = RegisterForm(request.POST)message = "请检查填写的内容!"if register_form.is_valid(): # 获取数据username = register_form.cleaned_data['username']password1 = register_form.cleaned_data['password1']password2 = register_form.cleaned_data['password2']email = register_form.cleaned_data['email']sex = register_form.cleaned_data['sex']if password1 != password2: # 判断两次密码是否相同message = "两次输入的密码不同!"return render(request, 'login/register.html', locals())else:same_name_user = models.User.objects.filter(name=username)if same_name_user: # 用户名唯一message = '用户已经存在,请重新选择用户名!'return render(request, 'login/register.html', locals())same_email_user = models.User.objects.filter(email=email)if same_email_user: # 邮箱地址唯一message = '该邮箱地址已被注册,请使用别的邮箱!'return render(request, 'login/register.html', locals())message = "注册成功!"# 当一切都OK的情况下,创建新用户# 创建用户信息//有问题:放在创建用户表后面会出现DJANGO pymysql.err.IntegrityError:# (1062, "Duplicate entry '' for key 'user_name'")new_user_data = user_data.objects.create()new_user_data.user_name = usernamenew_user_data.user_true_name = '无'new_user_data.user_id = '无'new_user_data.user_school = '无'# new_user_data.user_f_score = 425# new_user_data.user_s_score = 0new_user_data.save()#创建用户表new_user = models.User.objects.create()new_user.name = usernamenew_user.password = password1new_user.email = emailnew_user.sex = sexnew_user.save()return redirect('/login/') # 自动跳转到登录页面register_form = RegisterForm()return render(request, 'login/register.html', locals())
3 个人信息及报名管理
(我将其放在了app名为home里面)
3.1 数据库模型设计
#home/models.pyfrom django.db import models# Create your models here.class exam_entry_table(models.Model):#考点信息表exam_id = models.CharField(verbose_name="考试编号",max_length=10)exam_type = models.CharField(verbose_name="考试类别",max_length=128)exam_point = models.CharField(verbose_name="考点",max_length=128)exam_time = models.CharField(verbose_name="考试时间",max_length=128)number = models.IntegerField(verbose_name="容量")entry_number = models.IntegerField(verbose_name="已报名数量",default=0)def __str__(self):return self.exam_pointclass Meta:# ordering = ['c_time']verbose_name = '考点'verbose_name_plural = '考点信息表'class user_entry_table(models.Model):#用户考试信息表email = models.EmailField(verbose_name="邮箱")exam_id = models.CharField(verbose_name="考试编号",max_length=10)exam_point = models.CharField(verbose_name="考点",max_length=128)def __str__(self):return self.emailclass Meta:# ordering = ['c_time']verbose_name = '用户考试信息'verbose_name_plural = '用户考试信息表'class user_data(models.Model):#用户信息表user_name = models.CharField(verbose_name="用户名",max_length=128, unique=True)user_true_name = models.CharField(verbose_name="真实姓名",max_length=128, null=True)user_id = models.CharField(verbose_name="身份证号",max_length=18, null=True)# user_img =user_school = models.CharField(verbose_name="在读学校",max_length=128)user_f_score = models.IntegerField(verbose_name="四级成绩", default=0)user_s_score = models.IntegerField(verbose_name="六级成绩", default=0)def __str__(self):return self.user_nameclass Meta:# ordering = ['c_time']verbose_name = '用户名'verbose_name_plural = '用户信息表'
3.2 注册模型
#home/admin.pyfrom django.contrib import admin# Register your models here.from . import modelsadmin.site.register(models.exam_entry_table) #考点信息表admin.site.register(models.user_entry_table) #用户考试信息表admin.site.register(models.user_data) #用户信息表
3.3 创建表单
#home/forms.pyfrom django import formsfrom captcha.fields import CaptchaFieldclass UserForm(forms.Form):username = forms.CharField(label="用户名", max_length=128, widget=forms.TextInput(attrs={'class': 'form-control'}))password = forms.CharField(label="密码", max_length=256, widget=forms.PasswordInput(attrs={'class': 'form-control'}))captcha = CaptchaField(label='验证码')class RegisterForm(forms.Form):gender = (('male', "男"),('female', "女"),)username = forms.CharField(label="用户名", max_length=128, widget=forms.TextInput(attrs={'class': 'form-control'}))password1 = forms.CharField(label="密码", max_length=256, widget=forms.PasswordInput(attrs={'class': 'form-control'}))password2 = forms.CharField(label="确认密码", max_length=256, widget=forms.PasswordInput(attrs={'class': 'form-control'}))email = forms.EmailField(label="邮箱地址", widget=forms.EmailInput(attrs={'class': 'form-control'}))sex = forms.ChoiceField(label='性别', choices=gender)captcha = CaptchaField(label='验证码')
3.4 路由及视图设计
3.4.1 路由设计
这里用到的路劲较为复杂,采用项目urls和app的urls结合起来避免项目的urls过于拥挤。
先修改项目的urls.py文件:
#项目名/urls.pypath('homepage/',include('home.urls')), #前面已经添加了,这里只做说明
再修改app中的urls.py文件:
#home/urls.py
from django.contrib import admin
from django.urls import path,include
from home import views
urlpatterns = [
path('test/', views.test),
path('my_data/',views.mydate), #我的信息
path('query_results/',views.query), #查询报告信息
path('cet_4/',views.cet_4), #四级报名
path('cet_6/',views.cet_6), #六级报名
path('change_my_data/',views.updata),
]
3.4.2 视图设计
#home/views.pyfrom django.shortcuts import render, redirectfrom . import modelsfrom .forms import user_entry, user_datasfrom django.http import HttpResponse,HttpResponseRedirect# from django.contrib.auth.models import Userfrom login.models import User# Create your views here.def test(request):passreturn render(request, 'home/test.html')#我的信息def mydate(request):username = request.session.get('user_name', None)account = User.objects.get(name=username)#用户登录注册表user = models.user_data.objects.get(user_name= username)return render(request,"home/myself.html",{"user":user, "account":account})#修改我的信息def updata(request):username = request.session.get('user_name', None)# print("-----------------------")# print(username)# print("-----------------------")user_da = models.user_data.objects.get(user_name=username)user = User.objects.get(name=username)#login_user表if request.method == "POST":userdata = user_datas(request.POST)# print(userdata)if userdata.is_valid():user_das = userdata.cleaned_data# user.user_name = user_da['user_name'] #用户无法修改用户名user.email = user_das['email']user_da.user_true_name = user_das['user_true_name']user_da.user_id = user_das['user_id']user_da.user_school = user_das['user_school']user_da.save()user.save()# 四六级成绩无法修改# user_datas.user_f_score = user_da['user_f_score']# user_datas.user_s_score = user_da['user_s_score']return redirect('/homepage/my_data/')else:userdata = user_datas(initial={"email":user.email,"user_name":user_da.user_name,"user_true_name":user_da.user_true_name,"user_id":user_da.user_id,"user_school":user_da.user_school})return render(request, 'home/change_mydata.html', {"userdata":userdata})#查询考试信息 还没完成,优化,条件判断def query(request):username = request.session.get('user_name',None)user = User.objects.get(name=username)#用于判断用户是否报名user_en = models.user_entry_table.objects.filter(email=user.email)# print("********************")# print(user_en)# print(user_en[0])if user_en:# print(len(user_en))if len(user_en)==1:user_entry = models.user_entry_table.objects.get(email=user.email)user_point = user_entry.exam_pointuser_eid = user_entry.exam_idexam_entry = models.exam_entry_table.objects.get(exam_point=user_point, exam_id=user_eid)return render(request, 'home/query1.html', {"exam_entry": exam_entry})else:user_entry4 = models.user_entry_table.objects.get(email=user.email, exam_id=0)user_entry6 = models.user_entry_table.objects.get(email=user.email, exam_id=1)user_point4 = user_entry4.exam_pointuser_point6 = user_entry6.exam_pointexam_entry4 = models.exam_entry_table.objects.get(exam_point=user_point4, exam_id=0)exam_entry6 = models.exam_entry_table.objects.get(exam_point=user_point6, exam_id=1)return render(request, 'home/query2.html', {"exam_entry4": exam_entry4, "exam_entry6":exam_entry6})else:# message = "你还未报名!请先报名之后再来查看!"# return render(request, 'login/index.html', locals())user_da = models.user_data.objects.get(user_name=user.name)school = user_da.user_schoolif school=='无':message = "请先更新你的学校信息!"return render(request, 'login/index.html', locals())else:point = models.exam_entry_table.objects.filter(exam_point=school)if point:if len(point)==1:exam = models.exam_entry_table.objects.get(exam_point=school)return render(request, 'home/exam1.html', {"exam": exam})else:exam4 = models.exam_entry_table.objects.get(exam_point=school, exam_id=0)exam6 = models.exam_entry_table.objects.get(exam_point=school, exam_id=1)return render(request, 'home/exam2.html', {"exam4": exam4, "exam6": exam6})else:message="你的学校还未开放报名!详情请咨询学校相关部门!"return render(request, 'login/index.html', locals())#四级报名def cet_4(request):username = request.session.get('user_name', None)# 用户信息表,用户表,获取信息判断资格user_da = models.user_data.objects.get(user_name=username)user = User.objects.get(name=username)if request.method == "POST":cet4_form = user_entry(request.POST)if cet4_form.is_valid():# 四级考试对分数无要求# 只需要获取报考考点信息即可# email = cet4_form.cleaned_data['email']exam_id = '0'exam_point = cet4_form.cleaned_data['exam_point']#用与下面的考点判断point = models.exam_entry_table.objects.filter(exam_point=exam_point, exam_id='0')# 用与下面的是否重复报名判断entryer = models.user_entry_table.objects.filter(email=user.email, exam_id=exam_id)#判断个人信息是否完善if user_da.user_true_name=='无'or user_da.user_id=='无':message="请先完善个人真实信息之后再来报名!"return render(request, 'home/cet_4.html', locals())# 判断是否重复报名# print("判断是否重复报名")elif entryer:message = "请勿重复报名!"return render(request, 'home/cet_4.html', locals())elif point:# 考点存在# print("没有重复报名")message = "报名成功!请按时参加考试!"# 创建一条数据new_user = models.user_entry_table.objects.create()new_user.email = user.emailnew_user.exam_id = exam_idnew_user.exam_point = exam_pointnew_user.save()# 考点容量减1,报考人数加1exam_entry = models.exam_entry_table.objects.get(exam_point=exam_point, exam_id=exam_id)exam_entry.number -= 1exam_entry.entry_number += 1exam_entry.save()return render(request, 'home/cet_4.html', locals())else:message = "该学校还未开放报名!详情请咨询学校相关部门!"return render(request, 'home/cet_4.html', locals())cet4_form = user_entry(initial={"email": user.email, "user_name": user_da.user_name, "user_true_name": user_da.user_true_name,"user_id": user_da.user_id})return render(request, 'home/cet_4.html', locals())#六级报名:def cet_6(request):username = request.session.get('user_name', None)# 用户信息表,用户表,获取信息判断资格user_da = models.user_data.objects.get(user_name=username)user = User.objects.get(name=username)if request.method == "POST":cet6_form = user_entry(request.POST)if cet6_form.is_valid():# 只需要获取报考考点信息即可# email = cet4_form.cleaned_data['email']exam_id = '1'exam_point = cet6_form.cleaned_data['exam_point']f_score = user_da.user_f_score# 用与下面的考点判断point = models.exam_entry_table.objects.filter(exam_point=exam_point, exam_id=exam_id)# 用与下面的是否重复报名判断entryer = models.user_entry_table.objects.filter(email=user.email, exam_id=exam_id)# 判断个人信息是否完善if user_da.user_true_name=='无'or user_da.user_id=='无':message="请先完善个人真实信息之后再来报名!"return render(request, 'home/cet_6.html', locals())# 判断是否重复报名elif entryer:# print("判断是否重复报名")message = "请勿重复报名!"return render(request, 'home/cet_6.html', locals())# 判断考点是否存在elif point:# 考点存在#判断四级成绩是否合格if f_score >= 425:# print("报名成功!请按时参加考试!")# 创建一条数据message = "报名成功!请按时参加考试!"new_user = models.user_entry_table.objects.create()new_user.email = user.emailnew_user.exam_id = exam_idnew_user.exam_point = exam_pointnew_user.save()# 考点容量减1,报考人数加1exam_entry = models.exam_entry_table.objects.get(exam_point=exam_point, exam_id=exam_id)exam_entry.number -= 1exam_entry.entry_number += 1exam_entry.save()return render(request, 'home/cet_6.html', locals())else:message = "四级成绩大于425才能报名六级考试!"return render(request, 'home/cet_6.html', locals())else:message = "该学校还未开放报名!详情请咨询学校相关部门!"return render(request, 'home/cet_6.html', locals())cet6_form = user_entry(initial={"email": user.email, "user_name": user_da.user_name, "user_true_name": user_da.user_true_name,"user_id": user_da.user_id})return render(request, 'home/cet_6.html', locals())
到这里基本的后端都实现了。
4 项目最终框架展示

5 总结
成果展示:
注册:


主页:

管理端:

数据库设计问题:
由于此次设计在开始之时没有设计完善,数据库各表之间的关联存在问题,例如本次报名系统而言,用户信息最好添加手机号码,我本打算使用邮箱即可,但是推荐使用联系更快的电话号码等等问题。
附录: 整体项目包地址链接:
来源:https://blog.csdn.net/Afollower/article/details/98249499

(扫码关注,获取更多视频资源)




