项目简介:
验证用户登录,展示信息
开发环境:
python 3.6,pycharm,mysql 5.6.40
Django核心思想:MVT,解耦。
M:model,模型,负责与数据库交互
V:view,视图是核心,负责接收请求、获取数据、返回结果
T:template,模板,负责呈现内容到浏览器
Django命令:
创建项目:django-admin startproject 项目名称
创建应用:python manage.py startapp 应用名称
开启简易服务器:python manage.py runserver
生成迁移文件 python manage.py makemigrations
执行迁移 python manage.py migrate
Step1:创建项目 django-admin startproject login
目录说明:
manage.py:命令行工具,可以与Django项目进行交互
项目同名目录:项目的Python包
_init _.py:空文件,可以当做包被导入
settings.py:项目整体配置文件
urls.py:项目的URL入口
wsgi.py:项目与WSGI Web服务器入口
Step2:创建应用 python manage.py startapp peo
目录说明:
migrations:模型迁移时,迁移文件的存放路径及执行迁移时的数据源
admin.py:注册模型,后台站点管理
models.py : 是处理数据的,MVT中的M
tests.py : 测试
views.py : 处理业务逻辑,MVT中的V
Step3:模型设计
设计两张表,一张表为存储用户名及用户密码,另一张表存储用户个人信息。
在应用的model.py下,设计模型,代码如下`
from django.db import models
class PeoInfo(models.Model):
name = models.CharField(max_length=10)
pwd = models.CharField(max_length=20)
def __str__(self):
return self.name
class BodyInfo(models.Model):
high = models.IntegerField()
weight = models.FloatField()
gender = models.BooleanField()
people = models.ForeignKey(PeoInfo) # 外键
Step4:模型迁移
1.生成迁移文件 python manage.py makemigrations
2.执行迁移 python manage.py migrate
模型迁移前,需在项目中注册应用,若使用其他数据库,也需要配置
注册应用:在settings.py中的INSTALLED_APPS列表中,添加应用名称
数据库配置:以使用Mysql数据库为例:在settings.py的DATABASES字典中,配置如下参数:ENGINE,使用的数据库;NAME,数据库名称;USER,用户名;PASSWORD,密码;HOST,ip地址;PORT,端口号。
模型迁移后,会在对应数据库中创建两张表,表名格式为:应用名_表名
若想自定义属性,可在模型中定义Meta类,自定义表名:
class Meta:
db_table = '表名'
说明:当模型models.py中字段改变时,需要重新迁移,迁移时会报错。因在之前迁移时,相关用户信息已经在数据库中存在,解决方法如下:
1.使用默认的splite3数据库:
2.使用mysql数据库
Step5:后台管理
admin.site.register(PeoInfo)
,若想自定义管理界面可在admin.py中定义模型类管理。通过重写list_display来自定义显示内容。`from django.contrib import admin
from .models import PeoInfo, BodyInfo
class BodyAdmin(admin.ModelAdmin):
list_display = ['id',
'high',
'weight',
'people',]
admin.site.register(PeoInfo)
admin.site.register(BodyInfo,BodyAdmin)
Step7:URL配置
URL入口为settings中的ROOT_URLCONF,指向项目URL,项目的URL流向
1.项目URL配置
在项目urls.py中,增加url,这里直接指向应用url,可增加`namespace,重定向使用
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^S',include('peo.urls',namespace='peo'))]
2.应用URL配置
在应用中新建urls.py文件,可增加name,反向解析使用
urlpatterns = [
url(r'^$', index, name='index'),]
Step8:视图
在之前的访问中,我们都是用127.0.0.1:8000/admin来访问,这是django自带的模板,在Step7中,我们已经定义了其他url,匹配到的URL,会找到对应一个视图函数。在视图中,就需要处理业务逻辑,在这里我们首先定义一个首页的视图,这个视图返回的模板显示一个登陆界面。
def index(request):
return render(request,'index.html')# 这里返回的index.html在后面说明
Step9:模板
Step8中,视图请求的模板,在这里我们先让这个模板展示一个用户登录的界面,在项目目录下新建Templates目录,用来存放模板。新建Templates目录后,需要到settings中设置模板查找的路径,TEMPLATES中’DIRS’:[os.path.join(BASE_DIR,
‘templates’)],新建index.html,构造一个form表单
<form action="/login" method="post">
{% csrf_token %}{# 这里的csrf是django自带的跨站请求伪造,在post请求中,必须带,或者去settings中禁用#}
用户名:<input type="text " name="uname"><br>
密码:<input type="password" name="upwd"><br>
<input type="submit" value="登录">
Step9:优化
在以上的说明中,当访问127.0.0.1:8000时我们仅拿到了一个登陆的界面,这个post请求到了/login,我们将项目逻辑流程罗列如下
1.判断用户是否存在,不存在 ->注册,存在 ->2
2.判断密码是否正确,不正确->重新输入,正确->3
3.判断用户信息是否完整。不完整->增加,完整,展示信息
Step9.1 新增登录检测的视图,配置其url及模板。
url:增加url(r'^login',login,name='login')
视图:
def login(request):
user = request.POST['uname'] # 获取请求中的用户名
pwd = request.POST['upwd'] # 获取请求中的密码
peolist = []
for prname in PeoInfo.objects.all():
peolist.append(prname.name) # 获取数据库中所有用户名
if user in peolist: # 判断用户是否存在
peo = PeoInfo.objects.get(name=user) # 获取数据库中用户名为输入用户名的对象
if pwd == peo.pwd: # 判断密码
body = peo.bodyinfo_set.all() # 获取对应人的信息
if len(body): # 判断人员信息是否完整
context = {'list': body,'peo': peo.name} # 构造上下文,传递到模板
return render(request, 'bodylist.html', context)
else: # 信息不完全,增加信息
return render(request,'bdmsg.html')
else: # 密码错误,重新填写
return render(request, 'index.html')
else: # 用户不存在,注册
return render(request, 'reg.html')
Step9.2:登录成功后,展示信息
在Step9.1中,我们判断用户名及密码后,需要展示人物信息,在login视图中,已经返回了人物信息模板‘bodylist.html’。代码如下
{% for body in list %}{#list为login视图中传递过来的上下文context字典的键#}
<ul>
姓名:{{ peo }}<hr>
身高:{{ body.high}} <hr> {#这里遍历模型中的bodyinfo对象,获取属性(字段)#}
体重:{{ body.weight }}<hr>
性别:{{ body.gender }}<hr>
ul>
展示如下:
Step9.3:注册视图
在Step9.1中,我们预留了当用户不存在需要注册的问题,在这里我们增加url及视图模板。
url:我们假定当判断不存在是,请求到/reg
模板:可以观察到,注册界面和登录界面有很多相同的地方,我们可以利用模板的继承来减少代码量,实现方法:在父模板中,利用{% block 标识名 %}来标记需要继承的代码块,在子模板中,先利用在这里我们还是先不用继承的方法,关于模板继承会在后面说到。reg.html
{% block haveuser %}
<h1> 用户不存在,请注册h1>
{% endblock %}
<form action="/reg" method="post">
{% csrf_token %}
用户名:<input type="text " name="uname"><br>
密码:<input type="password" name="upwd"><br>
<input type="submit" value="注册">
form>
视图:注册时和登录一样,先拿到数据库中的用户名,如果存在,则提示用户存在,重新注册,为简化起见,此处暂不考虑密码的规范性,也不需要两次输入密码
def reg(request):
pswd = request.POST['upwd'] # 获取post表单发来的密码
user = request.POST['uname']# 获取post表单发来的用户名
peolist = []
for prname in PeoInfo.objects.all():
peolist.append(prname.name) # 获取所有用户
if user in peolist: # 判断是否存在,重新注册
return render(request, 'reg.html')
newpeo = PeoInfo() # 创建人物对象
newpeo.name = request.POST['uname']
newpeo.pwd = request.POST['upwd']
newpeo.save()# 提交到数据库
return render(request, 'index.html')# 注册后,返回到首页登录界面
Step9.4 人物信息不完整添加
在Step9.1中,login视图中,当判断人物信息不完整时,需要去添加信息,及对应用户的BodyInfo中的属性。增加人物信息的模板bdmsg.html及对应视图
bdmsg.html
<form action="/bdmsg" method="post">
{% csrf_token %}
用户:<input type="text " name="uname"><br>
密码:<input type="password" name="upwd"><br>
身高:<input type="text " name="high"><br>
体重:<input type="text" name="weight"><br>
性别:<input type="text" name="gender"><br>
<input type="submit" value="修改/增加个人信息">
form>
视图bdmsg
def bdymsg(request):
name = request.POST['uname']
pwd = request.POST['upwd']
peo = PeoInfo.objects.get(name=name)
if peo.pwd == pwd:
bdmsg = BodyInfo()
bdmsg.high = request.POST['high']
bdmsg.weight = request.POST['weight']
bdmsg.gender = request.POST['gender']
bdmsg.people = PeoInfo.objects.get(name=name)
bdmsg.save()
context = {'list': peo.bodyinfo_set.all(),'peo':name}
return render(request,'bodylist.html',context)
else:
return render(request,'bdmsg.html')
url:增加url(r'^bdmsg',bdymsg)
Step9.5: 增加直接注册用户的链接及注册等错误信息提示。增加两个模板,errorpwd.html,继承index.html;。
1.用户密码错误提醒:
{% block user %}{% endblock %}
{% extends 'index.html' %}
{% block user %}
密码错误
{% endblock %}
else: # 密码错误,重新填写
return render(request, 'errorpwd.html')
2.首页增加注册用户链接
{% block nouser %}
还没有账号,去注册
{% endblock %}
url(r'^utr',utr,name='utr'),
视图中增加def utr(request):
return render(request,'reg.html')
以上完成用户登录注册及信息查询等,流程总结如下url匹配到视图,视图找到对应的模板去展示。本例仅为简易说明,尚有很多不完善的地方,可在注册验证密码时,增加验证码验证;也可通过权限判断,当判断为admin时,展示所有用户,并通过用户链接展示对应用户信息