Django框架学习day01-初识

1. 简介

Django 是用python语言写的开源web开发框架,并遵循MVC设计。

Django的主要目的是简便、快速的开发数据库驱动的网站。它强调代码复用,多个组件可以很方便的以"插件"形式服务于整个框架,Django有许多功能强大的第三方插件,你甚至可以很方便的开发出自己的工具包。这使得Django具有很强的可扩展性。它还强调快速开发和DRY(DoNotRepeatYourself)原则。

2. 特点

1) 重量级框架

对比Flask框架,Django原生提供了众多的功能组件,让开发更简便快速。

  • 提供项目工程管理的自动化脚本工具
  • 数据库ORM支持(对象关系映射,英语:Object Relational Mapping)
  • 模板
  • 表单
  • Admin管理站点
  • 文件管理
  • 认证权限
  • session机制
  • 缓存

2)MVT模式

有一种程序设计模式叫MVC,其核心思想是分工、解耦,让不同的代码块之间降低耦合,增强代码的可扩展性和可移植性,实现向后兼容。Django 的设计模式叫做MVT

  • M全拼为Model,与MVC中的M功能相同,负责和数据库交互,进行数据处理。
  • V全拼为View,与MVC中的C功能相同,接收请求,进行业务处理,返回应答。
  • T全拼为Template,与MVC中的V功能相同,负责封装构造要返回的html。

 

3. Django工程搭建

使用django 1.11.11版本,注意需要联网

pip install django==1.11.11

创建工程的命令为:

django-admin startproject 工程名称

创建的工程目录结构:

  • 与项目同名的目录,此处为demo。
  • settings.py 是项目的整体配置文件。
  • urls.py 是项目的URL配置文件。
  • wsgi.py 是项目与WSGI兼容的Web服务器入口。
  • manage.py 是项目管理文件,通过它管理项目。

运行服务器命令如下:可以不写IP和端口,默认IP是127.0.0.1,默认端口为8000

python manage.py runserver ip:端口
或:
python manage.py runserver

注:django默认工作在调式Debug模式下,如果增加、修改、删除文件,服务器会自动重启。按ctrl+c停止服务器。

4. 创建子应用

在Web应用中,通常有一些业务功能模块是在不同的项目中都可以复用的,故在开发中通常将工程项目拆分为不同的子功能模块,各功能模块间可以保持相对的独立,在其他工程项目中需要用到某个特定功能模块时,可以将该模块代码整体复制过去,达到复用。在Flask框架中也有类似子功能应用模块的概念,即蓝图Blueprint。在Django框架中叫做子应用。

在django中,创建子应用模块目录仍然可以通过命令来操作,即:

python manage.py startapp 子应用名称

子应用的目录结构:

  • admin.py 文件跟网站的后台管理站点配置相关。
  • apps.py 文件用于配置当前子应用的相关信息。
  • migrations 目录用于存放数据库迁移历史文件。
  • models.py 文件用户保存数据库模型类。
  • tests.py 文件用于开发测试用例,编写单元测试。
  • views.py 文件用于编写Web应用视图。

注册安装一个子应用的方法,即是将子应用的配置信息文件apps.py中的Config类添加到INSTALLED_APPS列表中。

'users.apps.UsersConfig'

创建视图:打开刚创建的users模块,在views.py中编写视图代码。

from django.http import HttpResponse

def index(request):
    """
    index视图
    :param request: 包含了请求信息的请求对象
    :return: 响应对象
    """
    return HttpResponse("hello the world!")

注:

  • 视图函数的第一个传入参数必须定义,用于接收Django构造的包含了请求数据的HttpReqeust对象,通常名为request
  • 视图函数的返回值必须为一个响应对象,不能像Flask一样直接返回一个字符串,可以将要返回的字符串数据放到一个HTTPResponse对象中。

在子应用中新建一个urls.py文件用于保存该应用的路由;在users/urls.py文件中定义路由信息

from django.conf.urls import url

from . import views

# urlpatterns是被django自动识别的路由列表变量
urlpatterns = [
    # 每个路由信息都需要使用url函数来构造
    # url(路径, 视图)
    url(r'^index/$', views.index),
]

在工程总路由demo/urls.py中添加子应用的路由数据

from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),  # django默认包含的

    # 添加
    url(r'^users/', include('users.urls')), 
]

5. 配置文件、静态文件

5.1 BASE_DIR

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

当前工程的根目录,Django会依此来定位工程内的相关文件,我们也可以使用该参数来构造文件路径。

注:abspath()# 这个表示绝对路径; dirname()# 这个表示父路径

5.2 DEBUG

调试模式,创建工程后初始值为True,即默认工作在调试模式下。

作用:

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

  • Django程序出现异常时,向前端显示详细的错误追踪信息,而非调试模式下,仅返回Server Error (500)

注意:部署线上运行的Django不要运行在调式模式下,记得修改DEBUG=False。

5.3 本地语言与时区

初始化的工程默认语言和时区为英语和UTC标准时区:

LANGUAGE_CODE = 'en-us'  # 语言
TIME_ZONE = 'UTC'  # 时区

将语言和时区修改为中国大陆信息:

LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'

5.4 静态文件

为了提供静态文件,需要配置两个参数:

  • STATICFILES_DIRS 存放查找静态文件的目录
  • STATIC_URL 访问静态文件的URL前缀
STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static_files'),
]

注意:Django 仅在调试模式下(DEBUG=True)能对外提供静态文件。当DEBUG=False工作在生产模式时,Django不再对外提供静态文件,需要是用collectstatic命令来收集静态文件并交由其他静态文件服务器来提供。

6. 路由说明

6.1. 路由定义位置

Django的主要路由信息定义在工程同名目录下的urls.py文件中,该文件是Django解析路由的入口。

每个子应用为了保持相对独立,可以在各个子应用中定义属于自己的urls.py来保存该应用的路由。然后用主路由文件包含各应用的子路由数据。

6.2. 路由解析顺序

Django在接收到一个请求时,从主路由文件中的urlpatterns列表中以由上至下的顺序查找对应路由规则,如果发现规则为include包含,则再进入被包含的urls中的urlpatterns列表由上至下进行查询。

值得关注的 由上至下 的顺序,有可能会使上面的路由屏蔽掉下面的路由,带来非预期结果。

注: 需要注意定义路由的顺序,避免出现屏蔽效应。

6.3  路由命名

在定义路由的时候,可以为路由命名,方便查找特定视图的具体路径信息。

1) 在使用include函数定义路由时,可以使用namespace参数定义路由的命名空间,如:

url(r'^users/', include('users.urls', namespace='users')),

命名空间表示,凡是users.urls中定义的路由,均属于namespace指明的users名下。

命名空间的作用:避免不同应用中的路由使用了相同的名字发生冲突,使用命名空间区别开。

2) 在定义普通路由时,可以使用name参数指明路由的名字,如:

urlpatterns = [
    url(r'^index/$', views.index, name='index'),
    url(r'^say', views.say, name='say'),
]

6.4 reverse反解析

使用reverse函数,可以根据路由名称,返回具体的路径,如:

from django.urls import reverse  # 注意导包路径

def index(request):
    return HttpResponse("hello the world!")

def say(request):
    url = reverse('users:index')  # 返回 /users/index/
    print(url)
    return HttpResponse('say')
  • 对于未指明namespace的,reverse(路由name)
  • 对于指明namespace的,reverse(命名空间namespace:路由name)

6.5 路径结尾斜线/的说明

Django中定义路由时,通常以斜线/结尾,其好处是用户访问不以斜线/结尾的相同路径时,Django会把用户重定向到以斜线/结尾的路径上,而不会返回404不存在。用户访问 index 或者 index/ 网址,均能访问到index视图。

注:虽然路由结尾带/能带来上述好处,但是却违背了HTTP中URL表示资源位置路径的设计理念。

7. 请求

HTTP协议向服务器传参的四种形式:

  1. URL地址传参. Users/1/hello.

  2. 查询字符串. www.meiduo.site/index.py?name=hosnoodles&name1=crayfish

  3. 请求体传参. body

  4. header头.

7.1.  URL路径参数

在定义路由URL时,可以使用正则表达式提取参数的方法从URL中获取请求参数,Django会将提取的参数直接传递到视图的传入参数中。

未命名参数按定义顺序传递, 如

# 在urls.py:
url(r'^weather/([a-z]+)/(\d{4})/$', views.weather),

# 在view.py:
def weather(request, city, year):
    print('city=%s' % city)
    print('year=%s' % year)
    return HttpResponse('OK')

命名参数按名字传递,如

# 在urls.py:
url(r'^weather/(?P<city>[a-z]+)/(?P<year>\d{4})/$', views.weather),

# 在views.py
def weather(request, year, city):
    print('city=%s' % city)
    print('year=%s' % year)
    return HttpResponse('OK')

7.2.  Django中的QueryDict对象

定义在django.http.QueryDict

HttpRequest对象的属性GET、POST都是QueryDict类型的对象

与python字典不同,QueryDict类型的对象用来处理同一个键带有多个值的情况

方法get():根据键获取值

如果一个键同时拥有多个值将获取最后一个值

如果键不存在则返回None值,可以设置默认值进行后续处理

方法getlist():根据键获取值,值以列表返回,可以获取指定键的所有值

如果键不存在则返回空列表[],可以设置默认值进行后续处理

# /weather/beijing/2018/?a=1&b=2&a=3
def weather(request, city, year):
    print(year)
    print(city)
    # 查询字符串参数
    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]

7.3. 查询字符串Query String

获取请求路径中的查询字符串参数(形如?k1=v1&k2=v2),可以通过request.GET属性获取,返回QueryDict对象。

注:查询字符串不区分请求方式,即假使客户端进行POST方式的请求,依然可以通过request.GET获取请求中的查询字符串数据。

 

7.4. 请求体

请求体数据格式不固定,可以是表单类型字符串,可以是JSON字符串,可以是XML字符串,应区别对待。

可以发送请求体数据的请求方式有POSTPUTPATCHDELETE

7.4.1 表单类型 Form Data

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

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方式的请求体表单数据。

7.4.2 非表单类型 Non-Form Data

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

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

7.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).

具体使用如:

def get_headers(request):
    print(request.META['CONTENT_TYPE'])
    return HttpResponse('OK')

7.6 其他常用HttpRequest对象属性

  • method:一个字符串,表示请求使用的HTTP方法,常用值包括:'GET'、'POST'。
  • user:请求的用户对象。
  • path:一个字符串,表示请求的页面的完整路径,不包含域名和参数部分。
  • encoding:一个字符串,表示提交的数据的编码方式。
    • 如果为None则表示使用浏览器的默认设置,一般为utf-8。
    • 这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值。
  • FILES:一个类似于字典的对象,包含所有的上传文件

8. 响应

视图在接收请求并处理后,必须返回HttpResponse对象或子对象。HttpRequest对象由Django创建,HttpResponse对象由开发人员创建。

8.1 HttpResponse

可以使用django.http.HttpResponse来构造响应对象。

HttpResponse(content=响应体, content_type=响应体数据类型, status=状态码)

也可通过HttpResponse对象属性来设置响应体、状态码:

  • content:表示返回的内容。
  • status_code:返回的HTTP响应状态码。

响应头可以直接将HttpResponse对象当做字典进行响应头键值对的设置:

from django.http import HttpResponse

def demo_view(request):
    # return HttpResponse('test python', status=400)
    # 或者
    response = HttpResponse('test python')
    response.status_code = 400
    response['Item'] = 'Python'
    return response

8.2 HttpResponse子类

Django提供了一系列HttpResponse的子类,可以快速设置状态码

  • HttpResponseRedirect 301
  • HttpResponsePermanentRedirect 302
  • HttpResponseNotModified 304
  • HttpResponseBadRequest 400
  • HttpResponseNotFound 404
  • HttpResponseForbidden 403
  • HttpResponseNotAllowed 405
  • HttpResponseGone 410
  • HttpResponseServerError 500

8.3 JsonResponse

若要返回json数据,可以使用JsonResponse来构造响应对象,作用:

  • 帮助我们将数据转换为json字符串
  • 设置响应头Content-Type为 application/json
from django.http import JsonResponse

def demo_view(request):
    return JsonResponse({'city': 'beijing', 'subject': 'python'})

8.4 redirect重定向

from django.shortcuts import redirect

def demo_view(request):
    return redirect('/index.html')

9.1 设置Cookie

可以通过HttpResponse对象中的set_cookie方法来设置cookie。

def demo_view(request):
    response = HttpResponse('ok')
    response.set_cookie('itcast1', 'python1')  # 临时cookie
    response.set_cookie('itcast2', 'python2', max_age=3600)  # 有效期一小时
    return response

9.2 读取Cookie

可以通过HttpRequest对象的COOKIES属性来读取本次请求携带的cookie值。request.COOKIES为字典类型

def demo_view(request):
    cookie1 = request.COOKIES.get('itcast1')
    print(cookie1)
    return HttpResponse('OK')

10. Session

10.1 启用Session

Django项目默认启用Session。

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',  # 默认开启session ,注释可关闭
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

10.2 存储方式

在settings.py文件中,可以设置session数据的存储方式,可以保存在数据库、本地缓存等

数据库:存储在数据库中,如下设置可以写,也可以不写,这是默认存储方式

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

本地缓存:存储在本机内存中,如果丢失则不能找回,比数据库的方式读写更快。

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

混合存储:优先从本机内存中存取,如果没有则从数据库中存取。

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

10.3 Redis

在redis中保存session,需要引入第三方扩展,我们可以使用django-redis来解决。

1) 安装扩展

pip install django-redis

2)配置

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

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值