Django框架之初识
前言
1. 什么是Web应用程序?
通过Web访问的应用程序,用户只需要有浏览器即可,不需要再安装其他软件
应用程序有两种模式:
C/S:C/S是客户端/服务器端程序,也就是说这类程序一般独立运行
B/S:浏览器端/服务器端应用程序,一般借助IE等浏览器来运行;本质上其实也是c/s架构
Web应用程序首先是“应用程序”,又有自己独特的地方:基于Web的,典型的浏览器/服务器架构的产物;即B/S模式。
2. HTTP协议
也称为超文本传输协议:规定了客户端与服务端消息传输的格式
1)HTTP协议的四大特性:
1.基于TCP/IP协议,作用于应用层的协议
2.基于请求响应:一次请求对应一次响应,服务器不会主动发数据
3.无状态:不会保留客服端状态
4.无链接:请求一次,响应一次,http断开链接(websocket补丁)
2)数据之请求响应
数据格式之请求:
请求首行
请求头(一堆k,v键值对)
(这里有个空行)
请求体(post请求携带的数据)
数据格式之响应:
响应首行
响应头(一堆k,v键值对)
(这里有个空行)
响应体(你想访问的数据资源)
3)响应状态码(status Code)
1xx:服务器已经成功接收到你的数据,正在处理,你可以继续提交其他数据
2xx:请求成功,返回相应资源
3xx:重定向
4xx:请求资源不存在
5xx:服务器内部错误(如服务器崩)
3. 动静态网页
1)静态网页
页面上的数据都是固定写死的
2)动态网页
后端获取数据库数据然后传递给前端页面,页面上的数据是从后端动态获取的
如后端获取当前时间:利用字符串替换html中特殊符号的部分
如获取数据库的数据
4. 模板渲染
后端生成的数据直接传递给前端页面使用(前端页面可以灵活的操作改数据)
>>> 通过模板语法实现,依赖于第三方模块jinja2
1)导入第三方模块
命令行:pip install jinja2
2)模板语法
jinja2支持前端直接使用,类似于python的语法操作数据
{{}}:跟变量相关
{%%}:跟逻辑相关
后端:
user_dic = {'name': 'Tom', 'password': '123'}
user_list = [{},{},{},{}]
前端:
<!--使用字典--> <p>{{ user_dic }}</p> <p>{{ user_dic.name }}</p> <p>{{ user_dic['password'] }}</p> <p>{{ user_dic.get('name') }}</p> <!--循环取值--> {% for user in user_list %} <!--[{},{},{},{}]--> <tr> <td>{{ user.id }}</td> <td>{{ user.name }}</td> <td>{{ user.password }}</td> </tr> {% endfor %}
5. django的进化过程
import socket server = socket.socket() # 不传参数默认就是TCP协议 server.bind(('127.0.0.1', 8080)) server.listen(5) while True: conn, addr = server.accept() # 阻塞 等待客户端链接 # 信息被发到内存 data = conn.recv(1024) # 向计算机内存要数据 conn.send(b'HTTP/1.1 200 OK\r\n\r\n') print(data) # 手动处理http数据获取用户访问的路径 current_path = data.decode('utf-8').split('\r\n')[0].split(' ')[1] if current_path == '/index': # conn.send(b'<h1>index</h1>') # 路由匹配上之后返回index with open('index.html','rb') as f: conn.send(f.read()) else: conn.send(b'404') # 当匹配不上的时候统一返回404 conn.close()
基于wsgiref模块:借助于wsgiref处理socket以及http数据
from wsgiref.simple_server import make_server from urls import * def run(env, response): response('200 OK', [('username', 'Tom')]) print(env) # 是个大字典 一堆处理好的键值对 # 获取用户访问路径 current_path = env.get('PATH_INFO') # if current_path == '/index': # return [b'index'] # elif current_path == '/login': # return [b'login'] # 定义一个存储函数名的变量名 func = None # 循环比对路由与视图函数的映射关系 for url_map in urls: if current_path == url_map[0]: func = url_map[1] # 只要匹配成功,直接结束循环 break if func: res = func(env) else: res = error(env) return [res.encode('utf-8')] if __name__ == '__main__': server = make_server('127.0.0.1', 8080, run) server.serve_forever()
from views import * urls = [ ('/index', index), ('/login', login), ('/reg', reg), ('/get_time', get_time), ]
import time def index(env): return 'index' def login(env): return 'login' def error(env): return 'error' def get_time(env): current_time = time.strftime('%Y-%m-%d %X') with open(r'templates/get_time.html', 'r', encoding='utf-8')as f: data = f.read() # 是以r模式打开的文件,得到的内容是字符串 res = data.replace("@time@", current_time) # 字符串的替换 return res def reg(env): return 'reg'
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> </head> <body> @time@ </body> </html>
基于jinja2模板渲染:
from views import * urls = [ ('/index', index), ('/login', login), ('/reg', reg), ('/get_time', get_time), ('/get_user', get_user), ]
from jinja2 import Template def get_user(env): with open(r'templates/get_user.html', 'r', encoding='utf-8') as f: data = f.read() tmp = Template(data) # 将字典传递给前端页面,前端通过变量名user_dic就可以获取到该字典 return tmp.render(user_dic={'name': 'jason', 'password': '123'})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> </head> <body> <p>{{ user_dic }}</p> <p>{{ user_dic.name }}</p> <p>{{ user_dic['password'] }}</p> <p>{{ user_dic.get('name') }}</p> </body> </html>
模板渲染数据库信息:
from views import * urls = [ ('/index', index), ('/login', login), ('/reg', reg), ('/get_time', get_time), ('/get_user', get_user), ('/get_db', get_db), ]
import pymysql def get_db(env): # 链接数据库,获取数据,渲染到前端页面 conn = pymysql.connect( host='127.0.0.1', port=3306, user='root', password='123', database='6m5d', charset='utf8', autocommit=True ) cursor = conn.cursor(pymysql.cursors.DictCursor) cursor.execute("select * from django3") user_dict = cursor.fetchall() # [(),(),()] with open(r'templates/get_db.html', 'r', encoding='utf-8') as f: data = f.read() tmp = Template(data) return tmp.render(user_dict=user_dict)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <table class="table table-hover table-striped table-bordered"> <thead> <tr> <th>web框架</th> <th>socket</th> <th>路由与视图函数</th> <th>模板渲染</th> </tr> </thead> <tbody> {% for user in user_dict %} <tr> <td>{{user.web}}</td> <td>{{user.socket}}</td> <td>{{user.rout}}</td> <td>{{user.template}}</td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> {{ user_dict }} <!--[(),(),()]--> </body> </html>
6.什么是Web框架?
a:socket
b:路由与视图函数对应关系
c:模板渲染
7.python三大主流框架
Django:大而全,自带了很多功能模块,类似于航空母舰 (缺点:有点笨重)
Flask:短小精悍,自带的功能模块特别少,大部分都是依赖于第三方模块(小而轻)
Tornado:异步非阻塞;主要用在处理高io、多路复用的情况,可以写游戏后端
web框架 | socket | 路由与视图函数 | 模板渲染 |
---|---|---|---|
Django | wsgiref | self | self |
Flask | werkzeug | self | jinja2 |
Tornado | self | self | self |
新建项目注意事项:**********
1.计算机的名称不能有中文
2.项目名不能起中文(可能乱码,无法执行)
3.一个pycharm窗口就是一个项目,不要多个项目放在一个窗口里面
Django简介
1.版本问题
LTS版本支持更新并提供技术帮助,推荐使用带LTS版本
命令行pip3 install django==1.11.11
推荐直接在Pycharm为我们提供的terminal终端下输入此命令,之后pycharm自动处理
2. 测试是否安装成功
django-admin
3. 创建Django项目的方式
1)方式一:命令行创建
创建 Django 项目:
django-admin startproject 项目名
创建 app 应用
python3 manage.py startapp app01
启动Django项目
python3 manage.py runserver
停止django项目
Ctrl+c
注意:用命令行创建django默认不会自动创建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', ], }, }, ]
2)方式二:pycharm创建
File >>> new project 选择django 注意项目名不能有中文,选择本机解释器,勾选后台管理
创建app:
① pycharm命令行:
python3 manage.py startapp app01
② Tools下面Run manage.py Task 功能栏:
startapp app01
启动:点击右向绿色的小按钮
注意:1.用django一定要保证只有一个在运行状态 切记切记!!!
2.一定记得清浏览器的缓存
3.Edit Configurations... 可以修改端口号
4.app(应用)的概念
一个项目相当于一个工厂,app就是里面的生产线
新创建的app需要在配置文件中注册才能生效
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config' # 全称 'app01' # 简写(任选一个) ]
5. django各个文件的作用
应用名下
migrations 数据库迁移记录相关数据
admin.py Django后台管理相关
models.py 模型表相关
views.py 视图函数
项目名下
settings.py 配置文件
urls.py 路由与视图函数的映射关系
templates
存放项目的所有页面文件(.html)
manage.py
Django入口文件
6. django小白必会
from django.shortcuts import render, HttpResponse, redirect
HttpResponse 返回字符串
redirect 重定向(路径)
render 返回 HTML页面并支持模板渲染
视图函数必将返回一个HttpResponse对象:redirect、render内部最终继承或返回该函数
render两种给前端页面传值的方式:
# 第一种方式:传递需要的变量 def reg(request): user_dict = {'name': 'Tom', 'password': '123'} return render(request, 'reg.html', {'user_dict': user_dict}) # 第二种方式:传递所有产生的变量 def reg(request): user_dict = {'name': 'Tom', 'password': '123'} return render(request, 'reg.html', locals())
7.关于重启客服端
一般情况下,修改了代码,就需要重启服务端
django识别到你的代码变化之后会自动重启,但有时候反应速度比较慢
这时候,可以手动重启,也可以多刷新几次浏览器