Python+Django后台交互

版权声明:Meter.Bulacn https://blog.csdn.net/qq_41500222/article/details/81461979

MVC,MVT概念:

MVC:

M全拼model 主要封装数据库的访问,对数据库中的数据库进行增,删,改,查操作。

V全拼view用于封装结果,生成页面展示的的HTML内容。

C全拼controller用于接收请求处理业务逻辑与model和view进行交互返回结果。

MVT:

M全拼model 与mvc的m功能相同,负责和数据库交互,进行数据处理。

V全拼view 与mvc中的c功能相同,接收请求,进行业务处理,返回应答。

T全拼template 与mvc中的v功能相同,负责封装构造返回html。

安装步骤:

安装虚拟环境:

第一条命令:
sudo pip install virtualenv
第二条命令:
sudo pip install virtualenvwrapper

上述不能执行使用第二种方法:

第一条命令:
sudo python3 -m pip install virtualenv
第二条命令:
sudo python3 -m pip install virtualenvwrapper

如果下载速度慢:

可以在命令后面加豆瓣源:

添加一个豆瓣源: -i https://pypi.douban.com/simple
  • 添加三句话(家目录下面的 .bashrc 如果你是用zsh 添加到.zshrc ) 要让我们的配置生效 soure .bashrc soure .zshrc

作用: 指定我们默认Python解释器的位置,指定我们virtualenvwrapper.sh的位置,python软件包和解释器安装的位置
如果看不懂详见:https://www.jianshu.com/p/6a34c1baee6a

用法:

创建虚拟环境:

mkvirtualenv + 虚拟环境名字 -p + python版本

p:后面加python版本可以不写

查看所有虚拟环境:

workon

切换虚拟环境:

workon + 要切换的虚拟环境名

删除虚拟环境:

rmvirtualenv + 要删除的虚拟环境名

退出虚拟环境:

deactivate

需要安装软件包Django:

pip install django==1.11

因为安装 django 1.11比较稳定

开始创建我们的第一个django项目:

创建项目:
django-admin startproject + 项目名称

项目结构:

python
manage.py #用于管理整个项目的核心模块
会有一个python包(包名和项目同名)
settings.py #项目的路由模块
urls.py #项目的路由模块
wsgi.py #django轻量级服务器
test.py #用于写单元测试的模块

创建应用:

1.需要先进入到那个目录下面
2.进入项目的目录下面输入命令

python manage.py startapp + 应用名

应用结构:

会有一个之前创建的应用包 包含:
models.py #模型 用于创建模型 跟数据库交互
view.py #接收请求,处理返回的结果模块
admin.py #后台管理站点
tests.py #测试模块
migrations(文件夹,python包)生成的迁移文件
__init__.py 第一次执行迁移这里会生成记录

手动注意点: 1. 使用pycharm打开 项目的时候需要吧应用安装到项目里面
INSTALL_APPS—-> booktest
2. 虚拟环境 我们切换成 我们需要的那个虚拟环境
3. template 文件夹(手动没有这个文件)

手动创建一个这样的文件夹
需要去 settings.py 模块里面 把这个文件夹的地址 配置进来
templates 未来我们放html文件地方

用pycharm 也可以直接创建 项目和应用  并且相关的配置  它都给你做好了  上手即用
版本: pro 专业版  
在配置文件里面,可以把我们的项目展示出来的内容由英文变成中文
LANGUAGE_CODE = 'zh-hans' # zh-Hans 繁体
TIME_ZONE = 'Asia/Shanghai'

ORM:

django里面有一个模块model.py 类对应数据库里面一张表,对象对应数据库里面的一横数据

例:

class Person(models.Model):
    book = models.CharFiled(max_length=20)
Person 对应数据库里面的一张表
p = Person() 一条数据

案例:

from django.db import models 
# django模块代表代表从django.db导入models模型

from datetime import datetime #导入时间模块

class BookInfo(models.Model):
    bname = models.CharField(max_length=20)
    bpub_date =models.CharField(default=datetime.now)

继承自models.Model去写我们自己的内容

CharField 代表 varchar类型
max_length 代表 最大长度

生成迁移文件:

python manage.py makemigrations

执行迁移文件:

python manage.py migrate

创建超级用户及站点管理:

后台管理 站点管理—>其实就是在管理你的数据库 通过界面而不是代码或者 sql语句

创建一个超级管理员
python manage.py createsuperuser
 将你的项目 python manage.py runserver 跑起来
 后台如果没有显示  各种模型 先去admin.py 文件里面 导入模型
 将模型注册到后台页面

简单操作

python manage.py  shell
  1. 导入对应的模型的模块
  2. 写代码 用django这个框架提供方式 来操数据库
# 往数据库里面写
1.  实例化一个对象 (模型-->表)
b = BookInfo()
2.  对象名.字段名    添加数据
b.bname = '射雕英雄传'
3.  保存操作的数据
b.save()
# 读
BookInfo.objects.all() # 列表,

模型类的名字.objects.all()是获取数据库里面所有的行——> 列表(里面装的是一个个对象)
模型类的名字.objects.get(id=1)是获取数据库里面的id=1的哪一条数据 —-> 对象
每一个对象 就是数据库里面的一行数据

小总结:
1. 模型类(model.py)
对应关系 类—-> 表 对象—-> 表里面一行
2. 你用Python写完一个类 不意味着数据库里面就有数据
1> 生成迁移文件
2> 执行迁移文件
3. 最最简单操作 通过 shell脚本来 临时
1. 添加
1> 导入模块(你要的模型类)
2> 添加 实例化一个对象 通过对象名.属性名 就可以添加一条数据 但是 在数据库里面 没有添加成功 因为 要 保存 对象名.save()
3. all get
模型类类名.objects.all()—>获取所有数据
模型类类名.objects.get(条件)—-> 满足条件的某一条数据

查询集表示从数据库中获取的对象集合,在管理器上调用某些过滤器方法会返回查询集,查询集可以含有零个、一个或多个过滤器。过滤器基于所给的参数限制查询的结果,从Sql的角度,查询集和select语句等价,过滤器像where和limit子句。

返回查询集的过滤器如下:

all()返回所有数据

filter()返回满足条件的数据

exclude()返回满足条件之外的数据,相当于SQL语句中where部分的not关键字

order_by()对结果进行排序

返回单个值的过滤器如下:

get()代表返回返回单个满足条件

count()返回当前查询结果的总数

aggregate()聚合 返回一个字典


利用AJAX获取get请求实现异步请求返回结果案例演示:

首先我们在pycharm的templates文件里创建两个html的模板 名字可以随便起 在案例中我们把两个名字一个设为json1.html和json2.html

如图:

这里写图片描述

紧接着我们在views.py文件中设置两个python函数来为templates展示页面

如图:


导入JsonResponse 它是HttpResponse的子选项
这里写图片描述
第一个函数代表获取数据
第二个函数代表返回结果

然后我们去配置这两个函数的路由也就是urls.py文件:

如图:

这里写图片描述
我们进入urls.py首先要做的第一件事情是要在book应用下导入views的文件数据(因为本人建的是book应用,我们在应用下面的urls.py去设置路由)
这里写图片描述
在这里我们运用到了反向解析这样使得路由地址更清晰更安全更简洁

这时我们就要在templates的两个模板里面去运用ajax去写我们的模板并实现异步请求及结果

我们首先在json1.html文件上进行书写

这里写图片描述
首先我们要配置jQuery的CDN 由于我们要方便简洁就可以在这里找到地址 但是重要的是每一次项目都必须联网
这里写图片描述
找到版本进行复制到json1.html中
这里写图片描述

接下来我们开始在json1.html绘制内容:这里写图片描述

我们首先要在body标签中去设置内容 这个配置流程就和我们平时写前端页面一样
button代表按钮 是我们即将用ajax获取结果的总指挥官
id为account和pwd代表利用ajax获取的账号密码结果之前的提示
那么我们去演示一下这个页面的概要信息
这里写图片描述

接着我们开始书写最重要的ajax的内容这时我会把每一个步骤的图片截下来翻译一遍请大家用心去看,其实学会了领略意思是非常简单的

这里写图片描述

首先我们要写一个script的标签在里面去写这个 那么我们看到这个会觉得有点乱
 所以我们在每一次碰到$的时候后面都会加一对括号就像这样$() 然后在括号里
 写上function(){}就像这样
 这样就会形成
 $(function(){
 })
 这段话的含义是接收上下文 据我感觉就是上文的cdn下文的body 这样才能接收
 并使用

这时我们开始写button把总指挥给写出来
这里写图片描述

首先我们写$()在括号里写$('#action')代表我们在body写的按钮在这里去
相互连接 然后后面要写监听事件在鼠标点击的时候会反馈一个请求 
$('#action').click() 紧接着在.click()的括号里写入function(){}这
代表回调函数把function里面的内容来给.click去支配 当我们点击 就会产
生这个请求$('#action').click(function(){
})

接下来我们要在回调函数的括号内用get请求获取view里的配置内容在json2.html来呈现结果
这里写图片描述
我们用反向解析的形式来配置json2的路径 此时大家会想 那json2在模板中写不写内容
其实不用因为我们早在view.py的文件中json2是JsonResponse来返回结果的的
这里写图片描述
当我们每一次点击按钮时会呈现json2的结果 由于我们没有在json2里设置内容所以显示的是空白
所以我们进行下一步操作
这里写图片描述
当我们获取get请求时 利用回调函数返回我们data也就是说我们在回调函数里面的数据 所以我们要把body里面的account和pwd利用.html函数去返回view里数据a的内容 和数据b的内容
这里写图片描述
这时我们去运行一下
这里写图片描述
这里写图片描述
所以我们在点击按钮的时候发出了一个get请求获取了view里的a数据和b数据
并用异步请求展现出来

cookie和session的区别:

cookie的缺点 cookie的键和值都存在浏览器的客户端里面 意味着安全性不高 本地可以有办法随意篡改

session 代表 客户端 向服务器发起请求 这时候服务器会有一张表 表里有两个字段 一个是 session的id 一个是session的值 然后在浏览器本地存了 一个cookie 这个cookie的键 是session id的值 当客户端又一次发起请求时 就带上这个上这个 session id


django登录实战

我们首先在pycharm创建新的一个项目和应用 项目名叫login_login 应用名叫login_user请看下图:

这里写图片描述
这里写图片描述

然后就create创建项目和应用

在mysql里面创建一个数据库为了保存您的账号密码等数据如下图:

这里写图片描述

创建了一个名叫loginA的数据库

然后我们进行settings的相关配置:

这里写图片描述
这里写图片描述
这里写图片描述

我们开始在models.py创建表的模型:

在这个模型中我们要设计 用户名,密码,邮箱地址,性别,创建时间

#设计一个User的模型类
class User(models.Model):
#设计一个元祖来给性别传值
    gender = (
        ('boy', '男孩'),
        ('gril', '女孩')
    )
    #设计用户名 最大长度为128 站点管理显示用户名字段 字段unique唯一不得重复
    name = models.CharField(max_length=128, verbose_name='用户名', unique=True)
    #设计密码 最大长度为256 因为可能会关系到加密问题所以在数据库里把字符调的长了一些
    password = models.CharField(max_length=256, verbose_name='密码')
    #设计邮箱 使用专门的EmailField类型
    email = models.EmailField(verbose_name='邮箱')
    #设计性别 把之前的gender利用choices来接收 设置字符长度10 默认为男
    sex = models.CharField(max_length=10, choices=gender, default='男', verbose_name='性别')
    #设计创建时间 使用专门的DateTimeField字段去设置
    t_time = models.DateTimeField(auto_now_add=True, verbose_name='时间')
    #人性化设计用户名 方便在站点管理显示
    def __str__(self):
        return self.name
        #设计Meta元信息 名字为用户表 复数形式也等于用户表
    class Meta:
        verbose_name = '用户表'
        verbose_name_plural = verbose_name

在项目包下的 init文件中设置 与pymysql的链接配置如下图:

这里写图片描述

随后我们在下方Terminal终端中输入命令 第一条命令代表 生成迁移 代表 把刚刚models.py设计的模型表 和一系列配置进行当前的生成 但是 这个是生成不带表 已经执行这里写图片描述

紧接着我们进行执行迁移

这里写图片描述

全是OK代表就是成功的

然后开始创建站点管理的超级用户

这里写图片描述

我们在应用下的admin.py中注册我们的模型表

这里写图片描述

首先导入应用下的models模型下的User应用
from .models import User
然后注册User模型
admin.site.register(User)

我们用命令开始登录服务器

这里写图片描述

用服务器地址登录admin

这里写图片描述

为了能让用户看到我们展示的页面 所以我们在templates文件中创建 4个html文件 这时我们选中templates右键 new 找到html 点击 会出现小框 一个一个就这样创建

这里写图片描述
这里写图片描述

这四个文件 base.html代表父模板 剩下的三个网页都要继承base.html 其中 这三个文件 index.html代表首页 login.html代表登录页 register.html代表注册页

然后开始设置应用下的views.py

#首先导入模型下的User表
from .models import User
#导入重定向
from django.shortcuts import redirect
#创建index首页函数 return返回首页前端模板
def index(request):
    return render(request, 'index.html')

#创建login登录函数 return返回登录页前端模板
def login(request):
    return render(request, 'login.html')

#创建register注册函数 return返回注册页前端模板
def register(request):
    return render(request, 'register.html')

#创建logout退出登录函数 return返回首页前端模板
def logout(request):
#重定向 退出登录直接跳转到首页
    return register('/index/')

然后我们开始在目录的文件下设置三个 html的路由配置

从应用下导入 view
from login_user import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    配置view的四个路由
    url(r'^index/$',views.index),
    url(r'^register/$',views.register),
    url(r'^login/$',views.login),
    url(r'^logout/$',views.logout)
]

随后我们在templates文件里面找到base.html 我们把他称作父模板 其他模板都继承他所以要干好多事情 首先我们要在这个模板中 写一个 导航条 和 登录注册的输入框

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>{% block title %}
        首页
    {% endblock %}</title>

    <!-- Bootstrap -->
    <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
      <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>
<body>
<nav class="navbar navbar-default">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#my-nav"
                    aria-expanded="false">
                <span class="sr-only">切换导航条</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">Mysite</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="my-nav">
            <ul class="nav navbar-nav">
                <li class="active"><a href="#">主页</a></li>
            </ul>
            <ul class="nav navbar-nav navbar-right">
                <li><a href="#">登录</a></li>
                <li><a href="#">注册</a></li>
            </ul>
        </div><!-- /.navbar-collapse -->
    </div><!-- /.container-fluid -->
</nav>
当子模板继承时 在这里设置block覆盖这里的内容
{% block content %}
{% endblock %}
{% block custom_css %}
{% endblock %}
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.min.js"></script>
</body>
</html>

有不懂这端代码详见:https://v3.bootcss.com/components/#navbar

然后我们用login.html继承base.html 在login.html写入继承base.html的模板 在block content 写了一个登录注册的form表单输入框 这里的 action=’/login/’ method=’post’ 当用户提交请求时 action会跳转到view里的login发出post请求:

{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}登录{% endblock %}
{% block css %}
    <link href="{% static 'css/login.css' %}" rel="stylesheet"/>{% endblock %}


{% block content %}
    <div class="container">
        <div class="col-md-4 col-md-offset-4">
            <form class='form-login' action="/login/" method="post">
                <h2 class="text-center">欢迎登录</h2>
                <div class="form-group">
                    <label for="id_username">用户名:</label>
                    <input type="text" name='username' class="form-control" id="id_username" placeholder="Username"
                           autofocus required>
                </div>
                <div class="form-group">
                    <label for="id_password">密码:</label>
                    <input type="password" name='password' class="form-control" id="id_password" placeholder="Password"
                           required>
                </div>
                <button type="reset" class="btn btn-default pull-left">重置</button>
                <button type="submit" class="btn btn-primary pull-right">提交</button>
            </form>
        </div>
    </div> <!-- /container -->
{% endblock %}

然后我们运行下服务器 看可不可以出现我们想象的界面

这里写图片描述

紧接着我们就开始绘制我们应用中的views.py里面的登录函数

含义:

def login(request):
#如果前端模板提交的是post请求 就执行以下操作
    if request.method == 'POST':
    #获取前端输入的用户名 和 密码
        username = request.POST.get('username',None)
        password = request.POST.get('password',None)
        #测试以下将账号密码打印出来 看有没有获取到
        print(username,password)
 #否则 当输入地址时跳转到登录页面
    else:
        return render(request,'login.html')

我们利用Pycharm的 Debug模式来测试前端传过来的值 并用print打印 看看有没有传过来

首先 点击右上角的虫子

这里写图片描述

其次 给选择感觉有疑义的一横代码打个红点 方便检测

这里写图片描述

最后 我们开启运行我们的代码 点击虫子旁边的左2 按钮开始

这里写图片描述

我们输入地址 打开我们的前端登录页面 点击提交

这里写图片描述

我们输入账号是 zhangsan 密码 123456

会出现禁止访问 csrf 安全 这是正确的

这里写图片描述

我们要在前端页面的form表单中加入csrf_token 请看代码

 <form class='form-login' action="/login/" method="post">
                 加在这里
                {% csrf_token %}
                <h2 class="text-center">欢迎登录</h2>
                <div class="form-group">
                    <label for="id_username">用户名:</label>
                    <input type="text" name='username' class="form-control" id="id_username" placeholder="Username"
                           autofocus required>
                </div>
                <div class="form-group">
                    <label for="id_password">密码:</label>
                    <input type="password" name='password' class="form-control" id="id_password" placeholder="Password"
                           required>
                </div>
                <button type="reset" class="btn btn-default pull-left">重置</button>
                <button type="submit" class="btn btn-primary pull-right">提交</button>
            </form>

然后 我们重新刷新页面 我们写一个跳到首页 我们的值就传过来了 很成功

这里写图片描述

我们开始接着写我们的逻辑 在写逻辑之前我们先回顾一下 首先 我们 在login 这个函数中 要写我们登录的内容 我们设立了一个判断 为了更加节省我们的代码 在代码中 我们设计 if request.method == ‘POST’这个代表 如果我们找到前端用POST发起了传值的请求并跳转到 我们这个函数中 我们就执行 POST的以下操作 在代码中我们看到 username = request.PoST.get(‘username’,None)和password = request.PoST.get(‘password ‘,None)代表 在前端我们传过来的账号密码 用两个变量来接收 这两个变量分别是username password 然后测试一下打印这两个变量里的值 并跳转到 首页

否则中的return render(request,‘login.html’)代表当输入地址时跳转的登录页

所以我们就在POST登录中写效验的功能

def login(request):
    if request.method == 'POST':
    #我们在这里设计消息 等于空字符方便 判断时使用
        message = ''
        username = request.POST.get('username',None)
        password = request.POST.get('password',None)
        #如果 账号密码
        if username and password:
        #将账号去除空格 并传给 username变量
            username = username.strip()

            #捕捉异常
            try:
            #获取数据库里User的表里的一条信息 用name字段对比 刚刚去除空格的username里的值
                user = User.objects.get(name=username)
                #如果 数据库里的密码 等于 前端传来的密码
                if user.password == password:
                #就重定向跳转到首页
                    return redirect('/index/')
                #否则
                else:
                #密码错误 并跳转到登录界面 并打印 密码错误提示
                    message = '密码错误'
                    return render(request, 'login.html', {'message': message})
            #除非
            except:
            #该用户不存在 并跳转到登录页 打印 该用户不存在
                message = '该用户名不存在'
                return render(request, 'login.html', {'message': message})
        #账号密码都正确并跳转到首页
        return redirect('/index/')


    else:
        return render(request,'login.html')
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}登录{% endblock %}
{% block css %}
    <link href="{% static 'css/login.css' %}" rel="stylesheet"/>{% endblock %}


{% block content %}
    <div class="container">
        <div class="col-md-4 col-md-offset-4">
            <form class='form-login' action="/login/" method="post">
        加入了message插件
                {% if message %}
                    <div class="alert alert-warning">{{ message }}</div>
                {% endif %}

                {% csrf_token %}
                <h2 class="text-center">欢迎登录</h2>
                <div class="form-group">
                    <label for="id_username">用户名:</label>
                    <input type="text" name='username' class="form-control" id="id_username" placeholder="Username"
                           autofocus required>
                </div>
                <div class="form-group">
                    <label for="id_password">密码:</label>
                    <input type="password" name='password' class="form-control" id="id_password" placeholder="Password"
                           required>
                </div>
                <button type="reset" class="btn btn-default pull-left">重置</button>
                <button type="submit" class="btn btn-primary pull-right">提交</button>
            </form>
        </div>
    </div> <!-- /container -->
{% endblock %}

然后 我们运行服务器测试一下 能否实现我们的功能

我们在admin站点中先设置个账号密码 然后在前端中进行输入匹配

这里写图片描述

然后开始 进行测试

先试输入正确的

这里写图片描述
这里写图片描述

在试 错误密码和 错误账号

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

大功告成


我们接下来 开始大变化 加入form表单 加入一个验证码的验证

首先我们在应用中创建一个forms.py文件 在里面写我们对账号密码的 登录需求

#从django导入 forms
from  django import forms
#设计一个USerForm类 必须传参form.Form
class UserForm(forms.Form):
#约束账号 登录字符长度最少为6 密码也是
    username = forms.CharField(label='用户名',min_length=6,max_length=128)
    password = forms.CharField(label='密码',min_length=6)

上述是理解含义 然后演变成 测试的时候写入这个结果

from django import forms

class 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'}))

然后我们开始设计view.py

from django.shortcuts import render
from .models import User
from django.shortcuts import redirect
#从 forms导入UserForm
from .forms import UserForm
# Create your views here.

def index(request):
    return render(request, 'index.html')


def login(request):
#如果前端获取的是POST请求
    if request.method == 'POST':
    #将UserForm里的值 传入到login_form中
        login_forms = UserForm(request.POST)
        message = ''
        #如果 将这些值产生有规律的
        if login_forms.is_valid():
        #就把账号传入到 username中 把密码传入到 password中
            username = login_forms.cleaned_data['username']
            password = login_forms.cleaned_data['password']


            username = username.strip()

            try:
                user = User.objects.get(name=username)
                if user.password == password:
                    return redirect('/index/')
                else:
                    message = '密码错误'
                    return render(request, 'login.html', locals())
            except:
                message = '该用户名不存在'
                return render(request, 'login.html', locals())

        return render(request,'login.html',locals())


    else:
        login_forms = UserForm()
        return render(request,'login.html',locals())



def register(request):
    return render(request, 'register.html')


def logout(request):
    return register('/index/')

紧接着开始修改前端

{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}登录{% endblock %}
{% block css %}
    <link href="{% static 'css/login.css' %}" rel="stylesheet"/>{% endblock %}


{% block content %}
    <div class="container">
        <div class="col-md-4 col-md-offset-4">
            <form class='form-login' action="/login/" method="post">

                {% if message %}
                    <div class="alert alert-warning">{{ message }}</div>
                {% endif %}

                {% csrf_token %}
                <h2 class="text-center">欢迎登录</h2>
                在这里把forms.py文件里面的内容放到这里 它会自己生成个form表单
                {{ login_forms }}
                <div class="form-group">
                    {{ login_form.username.label_tag }}
                    {{ login_form.username }}
                </div>
                <div class="form-group">
                    {{ login_form.password.label_tag }}
                    {{ login_form.password }}
                </div>

                <button type="reset" class="btn btn-default pull-left">重置</button>
                <button type="submit" class="btn btn-primary pull-right">提交</button>
            </form>
        </div>
    </div> <!-- /container -->
{% endblock %}

我们来为登录注册添加验证码插件

首先安装

pip install django-simple-captcha

然后在项目settings把captcha注册上

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'login_user.apps.LoginUserConfig',
    'captcha'
]

然后执行迁移

然后在urls.py配置路由

#导入include
from django.conf.urls import url,include
from django.contrib import admin
from login_user import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/$', views.index),
    url(r'^register/$', views.register),
    url(r'^login/$', views.login),
    url(r'^logout/$', views.logout),
    #配置路由
    url(r'^captcha', include('captcha.urls'))
]
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}登录{% endblock %}
{% block css %}
    <link href="{% static 'css/login.css' %}" rel="stylesheet"/>{% endblock %}


{% block content %}
    <div class="container">
        <div class="col-md-4 col-md-offset-4">
            <form class='form-login' action="/login/" method="post">

                {% if message %}
                    <div class="alert alert-warning">{{ message }}</div>
                {% endif %}

                {% csrf_token %}
                <h2 class="text-center">欢迎登录</h2>
                {{ login_forms }}
                <div class="form-group">
                    {{ login_form.username.label_tag }}
                    {{ login_form.username }}
                </div>
                <div class="form-group">
                    {{ login_form.password.label_tag }}
                    {{ login_form.password }}
                </div>
                在这里添加验证码的模块
                <div class="form-group">
                    {{ login_form.captcha.errors }}
                    {{ login_form.captcha.label_tag }}
                    {{ login_form.captcha }}
                </div>

                <button type="reset" class="btn btn-default pull-left">重置</button>
                <button type="submit" class="btn btn-primary pull-right">提交</button>
            </form>
        </div>
    </div> <!-- /container -->
{% endblock %}

我们来运行下服务器 看下前端页面

这里写图片描述

当我们每次刷新页面的时候数据库都会产生一个验证码 它是有过期时间的

这里写图片描述

在父模板base.html写入

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>{% block title %}
        首页
    {% endblock %}</title>

    <!-- Bootstrap -->
    <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
      <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>
<body>
<nav class="navbar navbar-default">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        导航条
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#my-nav"
                    aria-expanded="false">
                <span class="sr-only">切换导航条</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">Mysite</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
    状态保持的登录注册
        <div class="collapse navbar-collapse" id="my-nav">
            <ul class="nav navbar-nav">
                <li class="active"><a href="#">主页</a></li>
            </ul>
            <ul class="nav navbar-nav navbar-right">
                {% if request.session.is_login %}
                    <li><a href="#">{{ request.session.user_name }}</a></li>
                    <li><a href="/logout/">退出登录</a></li>
                {% else %}
                    <li><a href="/login/">登录</a></li>
                    <li><a href="/register/">注册</a></li>
                {% endif %}


            </ul>
        </div><!-- /.navbar-collapse -->
    </div><!-- /.container-fluid -->
</nav>
{% block content %}
{% endblock %}
{% block custom_css %}
{% endblock %}
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.min.js"></script>
</body>
</html>

在index.html页面写入session状态保持用户

{% extends 'base.html' %}
{% block title %}主页{% endblock %}
{% block content %}
    {% if request.session.is_login %}
        <h1>你好,{{ request.session.user_name }}!欢迎回来!</h1>
    {% else %}
        <h1>你尚未登录,只能访问公开内容!</h1>
    {% endif %}
{% endblock %}

login.html 继承 base.html

{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}登录{% endblock %}
{% block css %}
    <link href="{% static 'css/login.css' %}" rel="stylesheet"/>{% endblock %}


{% block content %}
    <div class="container">
        <div class="col-md-4 col-md-offset-4">
            <form class='form-login' action="/login/" method="post">

                {% if message %}
                    <div class="alert alert-warning">{{ message }}</div>
                {% endif %}

                {% csrf_token %}
                在这里 form传来的可以在这里输入账号密码传到views.py
                <h2 class="text-center">欢迎登录</h2>
                {{ login_forms }}
                <div class="form-group">
                    {{ login_form.username.label_tag }}
                    {{ login_form.username }}
                </div>
                <div class="form-group">
                    {{ login_form.password.label_tag }}
                    {{ login_form.password }}
                </div>
                <div class="form-group">
                    {{ login_form.captcha.errors }}
                    {{ login_form.captcha.label_tag }}
                    {{ login_form.captcha }}
                </div>

                <button type="reset" class="btn btn-default pull-left">重置</button>
                <button type="submit" class="btn btn-primary pull-right">提交</button>
            </form>
        </div>
    </div> <!-- /container -->
{% endblock %}

设计view.py

from django.shortcuts import render
from .models import User
from django.shortcuts import redirect
#从forms.py导入UserForm
from .forms import UserForm
# Create your views here.

def index(request):
    return render(request, 'index.html')


def login(request):
#如果session在登录状态 
    if request.session.get('is_login',None):
    #就直接登录
        return redirect('/index/')
        #如果 前端发起请求
    if request.method == 'POST':
    #前端传来的值放到UserForm传给 login_forms
        login_forms = UserForm(request.POST)
        #给message设计一个空字符 为了以后出现异常传递信息
        message = ''
        #如果 login_forms里的账号密码是规律的值
        if login_forms.is_valid():
        #就会把这些值 账号传给username 密码传给password
            username = login_forms.cleaned_data['username']
            password = login_forms.cleaned_data['password']

    #并把username的值去除空格 传递给 username
            username = username.strip()
    #捕捉异常
            try:
            #数据库User表中获取name字段中刚去除空格的username进行比对
                user = User.objects.get(name=username)
                #如果 数据库的密码 等于 传递过来的password
                if user.password == password:
                #发起请求进行登录 并进行session 传值存储状态保持
                    request.session['is_login'] = True
                    request.session['user_id'] = user.id
                    request.session['uesr_name'] = user.name
                    #登录成功并跳转到首页
                    return redirect('/index/')
               #否则
                else:
                #密码错误
                    message = '密码错误'
                    #返回到 登录页 发出密码错误的消息
                    return render(request, 'login.html', locals())
            #除非
            except:
            #该用户名不存在
                message = '该用户名不存在'
                #并返回 到登录页 发出该用户名不存在消息
                return render(request, 'login.html', locals())
        #失败就返回 登录页

        return render(request,'login.html',locals())

#否则 
    else:
    #给 UserForm实例化
        login_forms = UserForm()
        #并返回到登录页
        return render(request,'login.html',locals())


#注册页函数
def register(request):
    return render(request, 'register.html')

#退出登录
def logout(request):
#如果 session里面没有值 
    if not request.session.get('is_login'):
    #就跳转到首页
        return redirect('/index/')
     #删除session 的所有值
    request.session.flush()
    #并跳转到首页
    return redirect('/index/')


登录验证码输错示范

这里写图片描述

登录示范

点击登录

这里写图片描述

进入登录

这里写图片描述

退出登录


Nginx+uWSGI+Django部署

这里写图片描述

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

第一步 我们首先在阿里云 或者 腾讯云 购买云服务器 或者领取免费体验天数 由于我们使用的是 ubuntu 系统 那么就选这个系统 如果是16.04就选16.04版本 然后点击购买

第二部 我们点击控制台

在这里我们演示的是阿里云控制台 腾讯的也叫控制台

这里写图片描述

第三部 我们找到左方的云服务器

这里写图片描述

第四部 我们找到左方的实例选项

这里写图片描述

如果没有做系统 我们第一次要给云服务器做系统 彻底清空这个服务器

点击右边的更多

这里写图片描述
这里写图片描述

点击停止 然后点击更多更换系统盘

这里写图片描述

点击确认更换 按照下图 配置并确认更换

点击验证 并确认

这里写图片描述

等待…

这里写图片描述

成功√

这里写图片描述

腾讯云 重装系统 点击更多 重装系统就可以 然后 按照上述步骤去操作

这里写图片描述

第五步 我们复制公网的ip地址

这里写图片描述

第六步 我们打开本地的终端

没有 ssh 提前下载ssh

第七步 我们输入我们服务器的密码

ssh 写用户名@写公网IP

这里写图片描述

如果出现这种情况

这里写图片描述

删除选中的地址

这里写图片描述

在登入 点击yes并输入密码

这里写图片描述

第八步 我们配置我们的云服务器

首先更新软件的两条命令 由于它是超级用户 所以我们不用sudo 如果不是超级用户就要加入 sudo

第一条
sudo apt update

第二条
sudo apt upgrade

等待 下载完成

然后安装 python3 pip

sudo apt install python3-pip

安装 virtualenv

sudo pip3 install virtualenv

如果安装virtualenv报错 请不要紧张 我们有绝世秘籍

这里写图片描述

分析原因
locale是用来设置软件运行的语言环境,所以语言环境设置有问题

解决故障   复制这三条 命令 一条一条输入 在登入云服务器
重新设置语言环境,最简单的解决办法:
第一条
 echo "export  LC_ALL=en_US.UTF-8"  >>   /home/XXX/.bash_profile 代表(特定用户)
第二条
 echo "export LC_ALL=en_US.UTF-8"  >>  /etc/profile 代表(所有用户)
第三条
exit
然后重新登录,使用locale指令查看变量

开始安装

这里写图片描述

安装 virtualenvwrapper

sudo pip3 install virtualenvwrapper

配置三条命令

输入命令
vi .bashrc

复制这三条命令到文档
export WORKON_HOME=$HOME/.virtualenvs
export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
source /usr/local/bin/virtualenvwrapper.sh

激活
source .bashrc

这里写图片描述
这里写图片描述

创建虚拟环境

mkvirtualenv 项目名

这里写图片描述

退出 虚拟环境 并安装mysql数据库

退出虚拟环境
deactivate
安装 mysql数据库
sudo apt-get install mysql-server mysql-client

配置数据库 输入一遍密码在输一遍密码

这里写图片描述

然后安装 filezilla 这款软件可以将本地文件上传到云服务器

sudo apt-get install filezilla

这里写图片描述

将虚拟环境pip里面的插件放到桌面上

这里写图片描述

然后将备份的数据库 和 项目都放到桌面上

这里写图片描述

打开filezilla 配置 ip 用户名 密码 端口

这里写图片描述

然后 找到 桌面上的文件 鼠标右键upload上传

然后 进入数据库 创建个 和之前settings同样的库 然后退出 把 备份的数据库资料导入到云上的mysql数据库

这里写图片描述

进入虚拟环境 把备份的pip插件 导入到当前云虚拟环境上

这里写图片描述

进入你的项目

创建 一个conf文件夹

mkdir conf

vi 第一个文件 文件名是你的项目名加上 项目名_nginx.conf将里面将以下信息复制填写带双引号的信息

* Socket connection established *
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-130-generic x86_64)

# the upstream component nginx needs to connect to
upstream django {
# server unix:///path/to/your/mysite/mysite.sock; # for a file socket
server 127.0.0.1:8000; # for a web port socket (we'll use this first)
}
# configuration of the server

server {
# the port your site will be served on
listen      80;
# the domain name it will serve for
server_name "你的公网地址"; # substitute your machine's IP address or FQDN
charset     utf-8;

# max upload size
client_max_body_size 75M;   # adjust to taste

# Django media
location /media  {
    alias /home/ubuntu/"目录名"/static/media;  # 指向django的media目录
}

location /static {
    alias /home/ubuntu/"目录名"/static; # 指向django的static目录
}

# Finally, send all non-media requests to the Django server.
location / {
    uwsgi_pass  django;
    include     uwsgi_params; # the uwsgi_params file you installed
}
}

vi uwsgi.ini将以下信息复制填写带双引号的信息


    # mysite_uwsgi.ini file
    [uwsgi]

    # Django-related settings
    # the base directory (full path)
    chdir           = /home/ubuntu/"项目名"
    # Django's wsgi file
    module          = "项目名".wsgi
    # the virtualenv (full path)

    # process-related settings
    # master
    master          = true
    # maximum number of worker processes
    processes       = 10
    # the socket (use the full path to be safe
    socket          = 127.0.0.1:8000
    # ... with appropriate permissions - may be needed
    # chmod-socket    = 664

将项目包中setting文件 将一段static链接代码注释 填入另一种代码

STATIC_URL = '/static/'
#STATICFILES_DIRS = [
#    os.path.join(BASE_DIR, 'static'),
#]
STATIC_ROOT = os.path.join(BASE_DIR,'static/')
MEDIA_URL = '/media/'
# 放在django项目根目录,同时也需要创建media文件夹
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

CKEDITOR_UPLOAD_PATH = 'upload/'

安装nginx

sudo apt-get install nginx

安装uwsgi

pip install uwsgi

测试nginx有没有成功

ps aux|grep nginx

这里写图片描述

将配置文件加入到nginx的启动配置文件中(当然你也可以把文件直接拷贝进去)这里我们利用了软连接

sudo ln -s /home/ubuntu/"项目名"/conf/"项目名"_nginx.conf /etc/nginx/conf.d

确认称没成功

这里写图片描述

重启nginx

这里写图片描述

进入虚拟环境 进入项目 运行这个命令

python manage.py collectstatic

成功

这里写图片描述

进入虚拟环境 进入项目 进入conf文件夹 拉起uwsgi -i uwsgi.ini

这里写图片描述

然后 输入你的 公网:80/加上你的路由首页

猜你喜欢

转载自blog.csdn.net/qq_41500222/article/details/81461979