Django基础
Python的WEB框架有 Django、Tornado、Flask 等多种,Django 相较与其他WEB框架其优势为:大而全,框架本身集成了ORM、模型绑定、模板引擎、缓存、Session等诸多功能。
安装
可以用pip3安装: pip3 install django
或者也可以通过PyCharm来安装:File-->Settings-->Project
安装完后,看一下Scripts目录,也就是你的pip3程序所在的目录,多了2个django-admin程序。这个是帮我创建Django程序的。
创建Django项目
将Script加到环境变量里去,就可以在任意地方创建Django,路径为:D:PythonPython36-32Scripts
通过dos命令创建Django
django-admin startproject mysite1
现在进入你的项目目录,启动你的项目,命令如下。默认参数是 127.0.0.1:8000 ,可以输入方框号中完整的IP和端口号来指定,比如:0.0.0.0:9001。
python manage.py runserver 127.0.0.1:8000
然后可以打开浏览器访问 http://127.0.0.1:8000/ 你的测试页了,能成功访问则说明上面的步骤都正确了
通过PyCharm来完成
PyCharm里面去。File-->New projct-->Django 里面创建
Location 里修改一下项目的路径和项目名,默认项目名是untitled,改掉。
Project Interpreter 里选择python环境,可以新建一个环境,或者使用已有的环境。
More Settings 里默认会帮我们创建templates文件夹。如果需要,还可以把 Application name 填上,就是创建项目的同时创建一个app。
创建一个页面
在项目下新建一个文件夹存放我们的页面,文件夹下新建一个python程序
目录:core-s1
from django.shortcuts import HttpResponse def hello(request): return HttpResponse("hello web!")
在urls.py中添加如下绑定
from django.contrib import admin from django.urls import path from core import s1 //导入s1 urlpatterns = [ path('admin/', admin.site.urls), path('hello/', s1.hello), ]
在dos中重新输入python manage.py runserver 127.0.0.1:8000 ,如果之前没有退出来,修改代码后,程序会默认重启的
此时输入http://127.0.0.1:8000 页面不会显示我们想要的内容,页面上显示两个后缀的内容,再次在浏览器打开http://127.0.0.1:8000/hello/,此时会显示我们让浏览器要显示的内容
创建app
通过创建app,相当于在网站下创建了一个相对独立的功能模块。我们可以创建多个app,为网站建立多个功能模块。创建的方法,是在命令行下输入命令:
python manage.py startapp
功能模块的名字
创建完之后,你的项目里又多了一个文件夹(app的名字),以及一些文件
其中views是给我放置处理函数的,把前面写的处理函数移动到这个文件里。然后再去 urls.py 里修改一下。
在 cmdb/views.py文件的后面追加我们的处理函数:
#views 中的代码 from django.shortcuts import HttpResponse def hello(request): return HttpResponse("<h1>hello web!</h1>")
#urls中添加的代码 from cmdb import views urlpatterns = [ path('admin/', admin.site.urls), path('hello/', views.hello), ]
以上执行结果和之前自己创建一个文件夹,在里面再创建一个文件写入代码是一样的
功能文件介绍
templates文件夹 :默认不会创建这个文件夹,不过使用PyCharm创建项目的时候会为我们创建它。存放我们的html文件。
settings.py :配置文件
urls.py :url的对应关系
wsgi.py :遵循WSGI规范,默认用的是wsgiref。老师推荐上线的系统用 uwsgi 替换掉默认的,也是这里改。推荐 uwsgi + nginx 。
manage.py :管理Django程序。有很多功能通过命令行参数控制,比如前面用的 runserver 和 startapp
app下的文件
migrations文件夹 :存放数据库操作的记录,是修改表结构的记录,不包括数据修改的记录。我们可以不用管这个文件夹里的内容
admin.py :Django提供的后台管理
apps.py :配置当前app的
models.py :创建数据库表结构,就是我们的ORM
tests.py :单元测试
views.py :业务代码
文件结构大致如下
写一个登录页面
创建html页面文件,templates/login.html :

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> label{ width: 80px; text-align: left; display: inline-block; } #sb{ margin: 0 150px; } </style> </head> <body> <div style="text-align: center; 300px" >用户登录</div> <form action="/login/" method="post"> <p> <label for="">用户名:</label> <input id="name" type="text"/> </p> <p> <label for="">密码:</label> <input id="pwd" type="text"/> </p> <input id="sb" type="submit" value="提交"/> </form> </body> </html>
注:这里的form表单中的action = "/login/",最后一个斜杠需要和urls.py中绑定的url一致
这里注意"/login/"结尾的"/"。浏览器中我们不输最后一个"/",但是Django默认会帮我们加上
但是代码里的,不会自动添加。加不加最后的"/",对程序而言就是两个url。
我们在urls.py里写的是带"/"的,写不对会导致找不到url。
不过Django会判断出来是因为你的url最后没加"/",会提示你去settings.py里加一条APPEND_SLASH=False。
人家默认开启是有意义的,我们需要做的就是别忘记在url最后写上各个"/"
在app里创建页面,views.py 里不再返回字符串,而是去读取html文件。

from django.shortcuts import HttpResponse def login(request): f = open("templates/login.html","r",encoding="utf-8") data = f.read() f.close() return HttpResponse(data)
在mysite1里修改urls.py

from cmdb import views urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.login), ]
以上我们就完成了一个登录页面,但是如果我们有很多文件,每个文件都需要用上面的方式打开,会很麻烦,这里Django给我们提供了一个renger,可以直接打开文件,读取文件。
这里只需要修改views.py,导入render,返回render()
from django.shortcuts import render def login(request): return render(request,"login.html")
显示 TemplateDoesNotExist at /login/,需要去settings设置下变量 TEMPLATES路径‘

TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
报错是因为'DIRS':[] 为空,需要我们添加下:
'DIRS': [os.path.join(BASE_DIR, 'templates')],
这样就将templates绝对路径加入了
引入静态文件
网页中还需要引入css模板,jQuery文件等,现在尝试把这些加上。
建立一个文件夹 “static” 来存放这些静态文件。然后创建一个css文件 “commons.cc” 给body加一个背景色:

body{ background-color: bisque; }
将Jq也放到static文件夹下,在login.html文件中导入css和jq

<link rel="stylesheet" href="/static/commons.css" /> //头部加 <script src="/static/jquery-3.2.1.min.js"></script> //body中加
再次运行程序,此时发现背景色并没有加上,使用F12查看,发现报错,找不到css和Jq,这是因为Settings没有将静态的文件路径配置上,需要我们手动去添加这个路径,记得要添加逗号

STATIC_URL = '/static/' #滑动到最后,放在STATIC_URL之后,添加如下这个配置, STATICFILES_DIRS = ( os.path.join(BASE_DIR,'static'), )
再次运行程序,此时背景色被添加上了
上面的引入方式,还是有问题。现在通过Django是可以全部访问了,但是本地打开html文件的时候是找不到引入的文件的。把路径的前面加上 ".." 表示上一级目录,就可以两边兼顾了:
<link rel="stylesheet" href="../static/commons.css">
Django请求
提交表单
上面已经实现了显示一个网页,现在我要将数据提交到后台处理,实现登录验证
网页代码如下login.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/commons.css" /> <style> label{ width: 80px; text-align: left; display: inline-block; } #sb{ margin: 0 0 0 150px; } </style> </head> <body> <div style="text-align: center; 300px" >用户登录</div> <form action="/login/" method="post"> <p> <label for="">用户名:</label> <input name="user" id="name" type="text"/> </p> <p> <label for="">密码:</label> <input name="pwd" id="pwd" type="text"/> </p> <input id="sb" type="submit" value="提交"/> <span style="color: red">{{ error_msg}}</span> </form> <script src="/static/jquery-3.2.1.min.js"></script> </body> </html>
现在要实现后台获取数据,并判断。
这里通过{{error_msg}}获取服务端提供实时值
通过Django给客户端返回动态的数据,需要用到模板自己的语言,该语言可以实现数据展示。这里要用到模板语言中的变量。
变量如下所示:{{ item }}。 当模板引擎遇到变量时,它将评估该变量并将其替换为结果。
这样在html中遇到用两个大括号包起来的形式,Django会把它替换成我们后端指定的内容
views.py的数据如下
from django.shortcuts import render from django.shortcuts import redirect def login(request): error_msg = "" #判断发送的是否为POST,为了是不处理get请求,点击提交是post请求,点击刷新是get请求 if request.method == "POST": #当是post请求,获取用户名密码 user = request.POST.get("user",None) pwd = request.POST.get("pwd",None) if user == "user" and pwd == "pwd": return redirect("http://www.baidu.com") else: error_msg = "用户名或密码错误" return render(request,"login.html",{"error_msg":error_msg})
提交有两种方式,一个是GET(内容在请求头),一个是POST(内容在请求体),当刷新网页时是GET,点击按钮时POST,
1.先通过判断是POST方式,
2.用户点击提交后,如果直接使用 user = request.POST [“user”] 通过下标获取,当用户没有输入内容时,会报错,所以一般使用 user = request.POST.get("user",None)
3.验证输入的和后台是否一致,如果一致,使用redirect()重定向,需要导入redirect;
如果不一致,提示用户输入错误,这里需要在html里面添加如span标签类的标签,标签内容使用{ { c错误提示内容 } },括号里面的内容需要和 return render(request,"login.html",{"error_msg":error_msg}) 最后一个字典中的key键一致
Django的模板语言
返回表格数据-for标签
Django的模板语言还支持循环,这样我们可以方便的获取一系列的数据,比如字典和列表。模板语句中叫做标签。
标签看起来像这样:{% tag %}。 一些标签需要开始和结束标签(即 {% tag %} ... 标签 内容 ... {% endtag %})
使用点(.)来访问变量的属性:
从技术上讲,当模板系统遇到点时,会按以下顺序尝试以下查找:
- 字典查找
- 属性或方法查找
- 数字索引查找
所以还可以用点来访问到字典或列表中的元素
实例:
通过for动态添加20条数据到后台,用到上面两个方法

#home.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="home/" method="post"></form> <table> <tr> <th>姓名</th> <th>性别</th> <th>邮箱</th> </tr> {% for item in user_list %} <tr> <td>{{ item.username}}</td> <td>{{ item.gender }}</td> <td>{{ item.email }}</td> </tr> {% endfor %} </table> </body> </html> #views.py from django.shortcuts import render from django.shortcuts import redirect def home(request): user_list = [ {"username":"aaa","gender":"女","email":"123@163.com"} ] for i in range(20): temp = {"username": "aaa"+ str(i), "gender": "女", "email": "123@163.com"} user_list.append(temp) return render(request,"home.html",{"user_list":user_list}) #urls.py中添加 path('home/', views.home),
实际效果如下面
现在我们要在页面上添加我们自己输入的数据到表格中

#home.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/home/" method="post"> <input type="text" name="username" placeholder="姓名" /> <input type="text" name="gender" placeholder="性别"/> <input type="text" name="email" placeholder="邮箱"/> <input type="submit" value="添加" /> </form> <table> <tr> <th>姓名</th> <th>性别</th> <th>邮箱</th> </tr> {% for item in user_list %} <tr> <td>{{ item.username}}</td> <td>{{ item.gender }}</td> <td>{{ item.email }}</td> </tr> {% endfor %} </table> </body> </html> #views.py from django.shortcuts import render user_list = [ {"username":"aaa","gender":"女","email":"aaa@163.com"}, {"username":"bbb","gender":"女","email":"bbb@163.com"}, {"username":"ccc","gender":"女","email":"ccc@163.com"}, ] def home(request): if request.method == 'POST': u = request.POST.get("username") g = request.POST.get("gender") e = request.POST.get("email") temp = {"username":u,"gender":g,"email":e} user_list.append(temp) return render(request,"home.html",{"user_list":user_list}) #usls.py path('home/', views.home),
一定要注意html中action中的写法,强烈建议在最后加/ :/home/
使用GET
使用GET提交一样,只需要将开始的判断改成request,GET == "GET"
if request.method == 'GET' and request.GET: name = request.GET.get('username') age = request.GET.get('gender') dept = request.GET.get('email')
get请求也可以直接通过浏览器的地址栏发出。在url的后面加问号(?),然后拼接上请求的内容:
http://127.0.0.1:8000/table/?username=aaa&gender=男&email=aa.163.com
url和请求之间用 ? 分隔,字段之间用 & 分隔,字段左边是 key 右边是 value 中间是 = 。
Djang请求的生命周期
下面是一个请求的整个流程,括号里是我们的代码存放的位置
请求 <--> 路由系统(urls.py) <--> 视图函数(views.py) <--> DB、html(templates)、静态文件(static)
内容整理
1.创建工程
django-admin startproject 工程名
2.创建APP
cd 工程名
python manage.py startapp cmdb
3.静态文件
进入settings,py
STARTFILES_DIRS = (
os.path.join(BASE_DIR,"static),
)
4.模板路径

TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
'DIRS' = [os.path。join(BASE_DIR,"templates)],
5.settings中
'django.middleware.csrf.CsrfViewMiddleware', 注释掉,没有注释无法进入网页测试
6.定义路由规则
urls.py

urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.login), path('home/', views.home), ]
7.定义视图函数
app下views.py
def func(request):
request.method GET / POST
request.GET.get("",None)
request.POST.get("",None)
return HttpResponse(("字符串")
return render(request,"html模板路径",{字典})
return redirect("/URL") #只能传/URL /表示前面的域名
8.模板渲染
模板语言:
--{{ 变量名 }}--
--for循环
{% for i in user_list %}
要循环的内容<li>{{ row }}</li>
{ % endfor %}
获取列表,字典中的值
<li>{{ list.0 }}</li> #获取列表下标为0的值
<li>{{ dict.k1 }}</li> #获取字典中key为k1的值
--条件-- if else及其嵌套
函数中有age = 10,需要在html中判断
{% if age %}
<a>有年龄</a>
{% if age >16 %}
<a>大</a>
{% else %}
<a>小</a>
{ % endif %}
{% else %}
<a>无年龄</a>
{ % endif %}
在pycharm中启动Django服务
1.要是直接运行manage.py程序的话 会提示一大堆东西,那无非是提示没有传入参数。先打开mange.py,然后再运行,会提示一堆东西,表示没有配置参数。在pycharm右上角
点击edit configurations 编辑配置参数。
2.点开之后弹出如下对话框,在parameters 对应的对话框中输入配置参数 runserver 127.0.0.1:8000.配置完成之后点击ok就完成了。