项目简介:

    验证用户登录,展示信息

开发环境:

    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数据库:

  • 直接删除sqlite3,及migrations中生成的迁移文件。然后执行
    python3 manage.py sqlmigrate 应用名称 0001,再执行迁移即可

2.使用mysql数据库

  • 直接删除数据库,重新建数据库
  • 根据models.py中字段的改变,不通过迁移,直接去操作数据库,使结构一致

Step5:后台管理

  • 创建超级管理员 python manage.py createsuperuser ,填写相关信息后创建完成。
  • 开启简易服务器 python manage.py runserver [ip:port] 若不写,默认为127.0.0.1:8000
  • (本地化,)可在settings.py中,修改语言及时区


    Step6:模型注册
    在应用admin.py中注册模型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.用户密码错误提醒:

  • 在index.html中,增加预留提示错误信息的区域
    {% block user %}{% endblock %}
  • 在errorpwd.html中,继承index.html,并填充错误信息

    {% extends 'index.html' %}
    {% block user %}
    <h1>密码错误</h1>
    {% endblock %}
  • 并在index视图判断密码不正确时返回errorpwd.html,修改如下
else:  # 密码错误,重新填写
    return render(request, 'errorpwd.html')

2.首页增加注册用户链接

  • 在index.html增加,
    {% block nouser %}
    <a href="{% url 'peo:utr' %}">还没有账号,去注册</a>
    {% endblock %}
  • 反向解析:{% url ‘peo:utr’ %} 格式为namespac:name,避免url混乱,这里也可以直接写链接
  • 上面当点击链接是,url转到了/utr所以这里我们再定义一个视图,模板返回注册模板即可。url中增加url(r'^utr',utr,name='utr'), 视图中增加
def utr(request):
     return render(request,'reg.html')

以上完成用户登录注册及信息查询等,流程总结如下url匹配到视图,视图找到对应的模板去展示。本例仅为简易说明,尚有很多不完善的地方,可在注册验证密码时,增加验证码验证;也可通过权限判断,当判断为admin时,展示所有用户,并通过用户链接展示对应用户信息

更多推荐

Django网站搭建步骤简介