Django框架学习(一)

2019-07-18 11:31:18 浏览数 (1)

1、知识回顾

1、POST/PUT/DELETE/PATCH访问一个url地址的时候才可以带请求体

2、状态码

200 请求成功

400 客户端请求有误

403 请求被拒绝

404 请求资源找不到

500 服务器发生错误

3、URL地址:协议、域名、端口、请求资源路径、请求参数

2、Django介绍

客户端->服务器

web服务器 Flask框架写项目代码

2.1 服务器介绍

服务器包括一个web服务器和web框架,他们直接遵循WSGI的协议

web服务器作用;解析请求报文,调用框架程序处理请求;组织响应报文,返回内容给客户端。

web框架程序作用:路由分发(根据URL找到对应的处理函数);调用处理函数进行业务的处理。

顺序

1、解析请求报文,调用框架程序处理请求

2、路由分发(根据URL找到对应的处理函数)

3、调用处理函数进行业务的处理

4、组织响应报文,返回内容给客户端

框架程序中所做的事:先构造一个HTTP请求对象(request),然后进行一个中间层处理(相当于Flask里面的请求钩子,钩子函数就是在请求之前或请求之后做一些事情),具体视图处理-业务处理(如数据库、模板、表单),再进行中间层处理,最终返回给服务器程序响应对象(response)

2.2 web程序框架的意义

用于搭建web应用程序,免去不同web应用相同代码部分的重复编写,只需关心web应用核心的业务逻辑实现

2.3 学习框架的步骤

1、先写一个helloworld程序(搭建工程程序:工程组建、配置、路由定义、视图函数定义);

2、再考虑如何获取请求数据(操作request对象);

3、再考虑构造响应数据(构造response对象);

4、然后考虑如何使用中间层;

5、最终就是考虑框架提供的其他功能组件怎么使用(数据库、模板和admin)

2.4 Django

强调快速开发、DRY原则(DoNotRepeatYourself

特点

1、重量级框架(相对于Flask来说,很多功能组件不需要自己再安装)

提供项目工程管理自动化脚本工具(对应Flask中的flask-script

数据库ORM支持(对应Flask中的FlaskSQLAlchemy

2、MVT模式(Model模型、View视图、Template模板)

Model模型:操作数据库

View视图:接收请求,进行业务处理、返回响应

Template模板:封装构造要返回的html,展示页面内容

3、MVT就是一种MVC,了解一下MVC即可

不同点

MVC中的View相当于MVT中的Template

MVC中的Controller相当于MVT里面的View一样

相同点:M相同

3、工程搭建

步骤

1、创建python3的虚拟环境

mkvirtualenv 虚拟环境的名字 -p python3

2、安装Django

pip install django==1.11.11

3、虚拟环境的相关命令

mkvirtualenv 创建虚拟环境

rmvirtualenv 删除虚拟环境

workon 进入虚拟环境(后面直接加要进入的虚拟环境的名字)、查看所有虚拟环境

deactivate 退出虚拟环境

pip install 安装依赖包

pip uninstall 卸载依赖包

pip list 已列表形式查看已安装的依赖包

pip freeze 查看已安装的环境的依赖包(没有上面的展示效果好看)

需要注意的小点

1、默认的端口是8000,默认的ip是127.0.0.1

2、一个项目分为很多功能模块,Flask里面的功能模块是蓝图,Django里面的功能模块是子应用

3、Django自带admin站点,我们想使用直接在admin.py中进行配置即可

3.1项目创建

创建项目:django-admin startprotect 项目名

创建子应用:python manage.py startapp 子应用名(先切换到项目的目录下,再创建)

子应用需要到INSTALLED_APPS中进行注册

工程目录说明

setting.py是项目整体配置文件

urls.py 是项目的URL配置文件(也就是我们常说的总的地址配置文件)

wsgi.py 是项目与WSGI兼容的Web服务器的一个入口

manage.py 是项目管理文件,通过它管理项目

子应用目录说明

admin.py文件跟网站的后台管理站点配置相关

apps.py文件用于配置当前子应用的相关信息

migrations目录用于存放数据库迁移历史文件

models.py文件用于保存数据库的模型类

tests.py文件用于开发测试用例,编写单元测试

views.py 文件用于编写web应用视图

3.2helloworld程序创建

1、在定义视图函数的时候,必须接收request(作为形参接收请求对象)

Flask框架中的视图函数可以直接返回字符串,但是Django视图返回的必须是响应对象

2、返回响应对象HttpResponse,相应对象中,传入响应的内容就可以了

3、在子应用下面创建一个文件urls.py,然后创建一个urlpatterns列表,然后再列表里面添加当前子应用中url地址和视图函数的对应关系url("url正则表达式","对应视图函数")。具体形式看下面,注意index前面的斜杆不写

url('^index/$',views.index)

4、在项目总的urls.py文件中包含子应用中的urls.py文件

代码语言:javascript复制
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^',include('users.urls')), # 包含users子应用下方的url文件
]

第二个url中正则表达式中不光可以写^匹配开头,还可以写一个前缀,进行匹配(这种情况在浏览器访问路径的时候就必须写前缀了)

4、路由说明

4.1 Django框架匹配的过程(十分重要)

我们访问地址,拿到地址/index之后,Django会先去总的urls中urlpatterns列表中从上到下开始匹配,匹配的时候将最前面的'/'去掉再匹配,匹配成功之后,去掉匹配成功的内容;将匹配剩下的内容到包含的子应用urls里面进行同样匹配,然后匹配成功,找到对应的视图函数,就会进行调用,然后给里面传一个request,最后就返回一个响应。

4.2 djano中url地址配置默认风格:在结尾加'/'

我们在浏览器中输入地址的时候没有加'/',加载的时候会先有一个重定向,然后自动帮我们加斜杠去访问

在工作中,以公司配置url地址的风格为准,可以进行更改

在子应用中进行url地址的配置时,建议严格匹配开头和结尾(防止访问时,视图混乱的情况,框架程序找错对应的视图函数)

4.3url地址反向解析

作用:根据视图函数动态获取对应的url,一般配合重定向时使用

Flask中使用方法

from flask import url_for

url_for('蓝图名.视图函数名')

在重定向的时候使用:redirect('/index')

重定向中使用反向解析的好处,将来视图函数的地址改变的时候,我们重定向是不需要更改的。

Django中使用方法

1、在子应用中地址配置时定义一个name参数,指明路由的名字

2、在总的地址配置里面进行包含的时候,定义一个namespace,一般名字和子应用的名字一样(注意写在include里面)

3、导入:

from django.urls import reverse

使用:

reverse('namespace:name')生成对应视图的url地址

例如:

req_rul = reverse('users:index')

5、Django配置文件

5.1BASE_DIR

BASE_DIRDjango项目的根目录路径,利用它生成一些项目里面的路径

在一个文件中打印__file__时,输入的结果是当前文件的绝对路径

os.path.abspath(__file__)获取的是绝对路径

os.path.dirname()获取的是本文件的上一级的绝对路径

5.2DEBUG

DEBUG默认为True,部署的时候改为False

作用

1、修改代码文件,程序自动重启

2、Django程序出现异常时,向前端显示详细的错误追踪信息

5.3语言时区本地化

语言时区本地化

LANGUAGE_CODE='en-us'语言改为中文'zh-hans'

TIME_ZONE = 'UTC'时区,改为中国时区'Asia/Shanghai'

5.4静态文件

项目中的CSS、图片和js都是静态文件。

设置静态文件存储的目录(需要自己设置)

STATICFILES_DIRS是一个列表,存放查找静态文件的目录,里面存放的路径我们不使用绝对路径,而是下面这样:

os.path.join(BASE_DIR, 'static_files')

设置访问金泰文件的url地址前缀(默认有,不设置也可以)

STATIC_URL = '/static/'

注意

Django 仅在调试模式下(DEBUG=True)的模式下对外提供静态文件。

当DEBUG=False工作在生产模式时,Django不再对外提供静态文件,需要使用collectstatic命令来收集静态文件并交由其他静态文件服务器来提供。项目部署的时候,debug会改为False,然后我们使用Nginx来提供静态文件。

6.请求与相应

6.1回顾

web开发中,客户端向服务器传递参数的途径

1、通过url地址传递参数

url地址:/users/<int:user_id>

2、通过请求体来传递参数

post表单,文件,json

3、通过请求头传递数据

代码语言:javascript复制
$ajax({
    type:'post',
    headers:{
        'X-CSRFToken':'值'
    }
})

4、通过查询字符串传递参数

在url地址中?后面的参数/index?a=1&b=2

6.2请求request

6.2.1URL地址中取参数

1、未命名参数按定义顺序传递

代码语言:javascript复制
url(r'^weather/(w )/(d{4})/$', views.weather),

def weather(request, city, year):
    print('city=%s' % city)
    print('year=%s' % year)
    return HttpResponse('OK')

2、命名参数按名字传递(推荐使用)

代码语言:javascript复制
url(r'^weather/(?P<city>w )/(?P<year>d{4})/$', views.weather),

def weather(request, year, city):
    print('city=%s' % city)
    print('year=%s' % year)
    return HttpResponse('OK')
6.2.2查询字符串中提取参数

Flask中利用request.args获取

Django中利用request.GET获取

获取请求路径中的查询字符串参数(形如?k1=v1&k2=v2),可以通过request.GET属性获取,返回QueryDict类的对象,类似于字典,但是和字典有区别,运行一键多个值(多个值获取利用request.GET.getlist)。

代码语言:javascript复制
# /qs/?a=1&b=2&a=3

def qs(request):
    a = request.GET.get('a')
    b = request.GET.get('b')
    alist = request.GET.getlist('a')
    print(a)  # 3
    print(b)  # 2
    print(alist)  # ['1', '3']
    return HttpResponse('OK')

重要:查询字符串不区分请求方式(get或post请求方式等都可以带查询字符串),即假使客户端进行POST方式的请求,依然可以通过request.GET获取请求中的查询字符串数据。

Django中默认有csrftoken验证,我们按自己需要关掉(在setting中的MIDDLEWARE中第四行)

表单get提交,是提交的查询字符串,post提交的是请求体

6.2.3获取post表单提交的数据

Flask中:request.form

Django中:request.POST

前端发送的表单类型的请求体数据,可以通过request.POST属性获取,返回QueryDict对象。

代码语言:javascript复制
def get_body(request):
    a = request.POST.get('a')
    b = request.POST.get('b')
    alist = request.POST.getlist('a')
    print(a)
    print(b)
    print(alist)
    return HttpResponse('OK')

重要:request.POST只能用来获取POST方式的请求体表单数据。

6.2.4获取json数据

1、利用request.body获取请求体中原始数据bytes类型

2、然后将bytes转换位str利用decode()

3、将json字符串转换为python字典,利用下面两种

json.dumps(dict)将python字典转换为json字符串

json.loads(json字符串)将json字符串转换为python字典

非表单类型的请求体数据,Django无法自动解析,可以通过request.body属性获取最原始的请求体数据,自己按照请求体格式(JSON、XML等)进行解析。request.body返回bytes类型。

例如要获取请求体中的如下JSON数据

代码语言:javascript复制
{"a": 1, "b": 2}

可以进行如下方法操作:

代码语言:javascript复制
import json

def get_body_json(request):
    json_str = request.body
    json_str = json_str.decode()  # python3.6 无需执行此步
    req_data = json.loads(json_str)
    print(req_data['a'])
    print(req_data['b'])
    return HttpResponse('OK')
6.2.5通过请求头获取数据

可以通过request.META属性获取请求头headers中的数据,request.META为字典类型

常见的请求头如:

CONTENT_LENGTH – The length of the request body (as a string).

CONTENT_TYPE – The MIME type of the request body.

HTTP_ACCEPT – Acceptable content types for the response.

HTTP_ACCEPT_ENCODING – Acceptable encodings for the response.

HTTP_ACCEPT_LANGUAGE – Acceptable languages for the response.

HTTP_HOST – The HTTP Host header sent by the client.

HTTP_REFERER – The referring page, if any.

HTTP_USER_AGENT – The client’s user-agent string.

QUERY_STRING – The query string, as a single (unparsed) string.

REMOTE_ADDR – The IP address of the client.

REMOTE_HOST – The hostname of the client.

REMOTE_USER – The user authenticated by the Web server, if any.

REQUEST_METHOD – A string such as "GET" or "POST".

SERVER_NAME – The hostname of the server.

SERVER_PORT – The port of the server (as a string).

具体使用如:

代码语言:javascript复制
def get_headers(request):
    print(request.META['CONTENT_TYPE'])
    return HttpResponse('OK')
Flask和Django中request对象属性的对比

method:一个字符串,表示请求使用的HTTP方法,常用值包括:'GET'、'POST'

user:请求的用户对象。

path:一个字符串,表示请求的页面的完整路径,不包含域名和参数部分。

encoding:一个字符串,表示提交的数据的编码方式。

如果为None则表示使用浏览器的默认设置,一般为utf-8。

这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值。

FILES:一个类似于字典的对象,包含所有的上传文件。

6.3响应response

视图可以返回HttpResponse类的对象或者子类的对象

构造响应对象的时候:

content_type默认是text/html

status默认是200

响应对象的子对象不需要记忆,下面的方式可以查找

from django.http import HttpResponse中的http可以点进去查看源代码,或者HTTPResponse中查看源代码

构造对象的时候,设置对象属性,两种方式:

代码语言:javascript复制
from django.http import HttpResponse

def demo_view(request):
    return HttpResponse('itcast python', status=400)
    或者
    response = HttpResponse('itcast python')
    response.status_code = 400
    response['Itcast'] = 'Python'
    return response
6.3.1响应时返回json数据

Flask中:jsonify

Django中:JsonResponse(<dict>)

Django中的JsonResponse(<dict>)其实先将字典转换成json字符串,然后将响应头Content-Type设置为 application/json

6.3.2响应时进行页面的重定向

flask和Django中的重定向是一样的redirect('重定向的url地址')

6.4cookie

6.4.1对比

特点

1、cookie数据保存在客户端,以key-value存储

2、cookie有过期的时间,默认是关闭浏览器过期

3、cookie基于域名安全的,浏览器在访问一个服务器时,只会把和跟这个服务器相关的cookie发送过去。

设置

代码语言:javascript复制
flask:

response = make_response(‘响应内容’)

response.set_cookie('<key>','<value>',max_age='<过期时间:s>')

Django:

response = HttpResponse('响应内容')

response.set_cookie('<key>','<value>',max_age='<过期时间:s>')

获取

代码语言:javascript复制
flask中:

request.cookies.get('<key>')

Django中:

request.COOKIES.get('<key>')

删除

代码语言:javascript复制
flask和Django一样

response.delete_cookie('<key>')

6.5session

6.5.1flask中session

特点

1、session数据保存在服务器,以key-value存储

2、session依赖于cookie,每个客户端的session信息标识(sessionID)保存在哭护短cookie中

3、session也有过期时间,flask开启session过期时间之后默认是30天,Django中session过期时间默认是2周。

设置

from flask import session

session['<key>'] = '<value>'

获取

session.get('<key>')

6.5.2django中session

存储方式

1、关系数据库:默认的存储方式(django_session)

SESSION_ENGINE='django.contrib.sessions.backends.db'

2、缓存:Django框架缓存默认是服务器内存

SESSION_ENGINE='django.contrib.sessions.backends.cache'

3、混合存储

SESSION_ENGINE='django.contrib.sessions.backends.cached_db'

4、将session信息存储到redis中

1、安装扩展包:

pip install django-redis

2、配置:

在settings.py文件中做如下设置

代码语言:javascript复制
# 设置Django框架的存储位置(如果不做设置,缓存默认是服务器内存)
# 此处是要把Django框架的缓存改为redis
# 缓存里面有多个小空间,我们可以设置多个
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        # 设置redis数据库地址
        "LOCATION": "redis://127.0.0.1:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
    "session": {
        "BACKEND": "django_redis.cache.RedisCache",
        # 设置redis数据库地址
        "LOCATION": "redis://127.0.0.1:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    } 
}
# 设置将Django框架的session存储到缓存中,上面已经将Django中的缓存改为了redis,所以session存储到了redis中
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
# 设置session存储到缓存空间的名称
SESSION_CACHE_ALIAS = "default"

3、设置session:

request.session['<key>']='<value>'·

4、获取session:

request.session.get('<key>')

注意

Django中默认是开启session的

框架会根据cookie中的sessionid到redis数据库中取到值,然后放到request.session中,我们就可以取到了。

优质文章推荐:

公众号使用指南

redis操作命令总结

前端中那些让你头疼的英文单词

Flask框架重点知识总结回顾

项目重点知识点详解

难点理解&面试题问答

flask框架中的一些常见问题

团队开发注意事项

浅谈密码加密

0 人点赞