Django框架的使用-基于Python

tech2023-02-10  115

Django框架的使用-基于Python

本文档介绍web框架中Django框架,基于Python。

1 基本概念

1.1 URL格式

Uniform Resource Locator,统一资源定位器, URL由三部分组成:资源类型、存放资源的主机域名、资源文件名。 也可认为由4部分组成:协议、主机、端口、路径

URL的一般语法格式为: (带方括号[]的为可选项): protocol : // hostname[:port] / path / [;parameters][?query]#fragment

protocol:协议,如http等。hostname:主机名、IP地址port:端口号path:路径parameters:参数,以?开始到#结束的区域传递参数query:查询fragment:信息片断

1.2 QueryDict 对象

这是是Django中的字典对象,与Python传统的字典对象不同的是:Python中的字典一个键只能对应一个值,而QueryDict允许一个键对应多个值。

QueryDict.get(key) 获取的是所有值的最后一个,只有一个值时获取当前值QueryDict.getlist(key) 获取这个键对应的所有值, 存放在列表中返回

2 工程基本配置

2.1 工程创建

2.1.1 创建

创建工程前应cd至想保持工程的木下

django-admin startproject 工程名称

创建目录如下:

2.1.2 工程各目录文件作用

2.1.2.1 配置文件——settings.py
BASE_DIR:指向当前工程的根目录 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

___file___ : 当前的文件 os.path.abspath ( 文件 ) : 获取这个文件的绝对路径 os.path.dirname( 路径 ) : 获取这个路径的上一级路径,两次即返回根目录

DEBUG:设置是否为调试模式,默认为True,在True情况下报错会显示具体错误信息。实际对外运行需要设置成False,同时要设置参数ALLOWED_HOSTS,设置允许访问的IP,*为所有。LANGUAGE_CODE:语言,‘zh-hans’ 中文TIME_ZONE:时区,‘Asia/Shanghai’ # 亚洲上海时区

2.2 运行

切换至创建的过程目录里

python manage.py runserver # 默认127.0.0.1:8000也可以选择在后面选择IP地址和端口

默认条件 运行效果在浏览器输入 127.0.0.1:8000

2.3 子应用

2.3.1 创建

cd至工程文件的根目录下

python manage.py startapp 子应用名称

创建的子应用目录

2.3.2 子应用目录各文件作用

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

2.3.3 添加子应用于工程

在工程文件里的settings.py文件里的INSTALLED_APPS添加类似“子应用名称.apps.NameConfig”(例’demo_1.apps.Demo1Config’,具体名字根据子应用的名字确定,可以在子应用的apps.py文件查看),如下

2.4 视图创建

2.4.1 视图编写

打开子应用目录下的views.py编写视图程序

def index(request): return HttpResponse("Hello World!") # 在页面输出Hello World!

2.4.2 定义路由URL

1.在子应用根目录下创建文件urls.py称子路由

from django.conf.urls import re_path from . import views # 导入自己编写的视图文件 # urlpatterns 是被 django 自动识别的路由列表变量 urlpatterns = [ # 每个路由信息都需要使用 url 函数来构造 # url (路径, 视图) re_path(r'^$', views.index), ]

re_path():包含四个参数

regex:正则表达式,其中的(?P<name>regex)会被传入view函数中与name相同的参数中,填写的为访问地址。例如上面的写法访问地址为:http://127.0.0.1:8000/demo_1,如果是’^index/$'则地址为:http://127.0.0.1:8000/demo_1/index 创建路由地址:re_path(/r’^inininin /$’, views.index),创建’子应用名字/inininin/’,以此格式书写 r’^inininin/$’ 可以防止访问路由时发生屏蔽。获取路由地址:reverse( ‘子应用名称 : 某路由名称’ )(from django.urls import reverse),返回路由地址为: ‘/子应用名称/某路由名称’ view:视图函数kwargs:字典类型,其中的键值对会按照随机顺序传入view函数中name:对本条URL进行别名,这样就可以在其他地方被引用。

2.在工程根目录下打开urls.py,修改urlpatterns参数

from django.contrib import admin from django.urls import path from django.conf.urls import include, url urlpatterns = [ path('admin/', admin.site.urls), url('demo_1/', include('demo_1.urls')), ]

3.运行manage.py(python manage.py runserver)

输入网址查看http://127.0.0.1:8000/demo_1/

3 参数传递

3.1 前端向后传递

3.1.1 URL查询字符传参

查询字符是在url中的parameters,是url地址中以’?‘开始以’#'结束的字符段。 可以在views.py文件编写视窗函数通过 request.GET 获取,返回为QueryDict 。

# url: http://127.0.0.1:8000/demo_1/get_url/?a=1&b=2&a=3#/ def get_url(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')

可以使用接口调试软件Postman进行参数传递: 软件会自动帮助输入调整网址

3.1.2 URL路径传参

在基础的视图设置中,我们的路径使用的是完整的路径名,要求完全匹配才能进行访问,而正则化是允许模糊匹配的,因此我们可以利用路径进行传参。

# url:127.0.0.1:8000/demo_1/get_path/adad/2020/ # views.py def get_path(request, name, year): '''定义weather函数, 接收路径参数''' print('name=%s' % name) # adad print('year=%s' % year) # 2020 return HttpResponse('OK') # 子路由 #url(r'^get_path/(?P<name>[a-z]+)/(?P<year>\d{4})/$', views.get_path), # 按名字传参 url(r'^get_path/([a-z]+)/(\d{4})/$', views.get_path), # 按顺序传参

3.1.3 请求体传参

请求体数据格式不固定,可以是表单类型字符串,可以是 JSON 字符串,可以是 XML 字符串,应区别对待。可以发送请求体数据的请求方式有 POST、PUT、PATCH、DELETE。测试时需关闭 CSRF 防护,在settings.py文件下的:

def get_POST(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')

可以在Postman软件传入参数

3.1.4 非表单类型传值的方式

# 获取方式: request.body # 得到的是 bytes 类型数据 # 可以通过 decode() 函数: 将 bytes 转为 str request.body.decode() # 可以通过 json.loads() 函数把 str 转为 dict json.loads(request.body.decode())

3.2 请求对象

3.2.1 头信息

通过 request.META 属性获取请求头中的数据 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). request.META['CONTENT_LENGTH'] # 获取长度,如:a=1&b=2,返回7

3.2.2 其他信息

使用request.内容来获取,如:request.内容包括:

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

3.3 响应

3.3.1 HttpResponse

from django.http import HttpResponse # 显示键值对 def demo_response(request): # 返回一个 HttpResponse 响应对象 return HttpResponse('{"name": "python"}', # 内容 content_type="application/json", # 内容数据类型 status=400) #状态码,返回数据的的 MIME 类型 def demo_view(request): # 创建一个 response 对象 response = HttpResponse('itcast python', status=400) # 在 response 对象中添加一个新的键值对 response['Itcast'] = 'Python' # 返回 response return response

3.3.2 JsonResponse

from django.http import JsonResponse def demo_view(request): # 直接返回 JsonResponse 这个对象,并且里面可以直接传入dict参数 dict_1 = { 'city': 'beijing', 'subject': 'python' } return JsonResponse(dict_1)

3.3.3 redirect

from django.shortcuts import redirect def demo_view1(request): # 第一种用法: 直接在 redirect 函数中添加路由字符串 return redirect('/users/index/') def demo_view2(request): # 第二种用法: 将 reverse 和 redirect 搭配使用 url = reverse('users:index') return redirect(url)

3.4 Cookie

用于储存一些用户的默认信息,信息储存于用户的电脑内,实现类似记住用户名之类的效果。

3.4.1 创建和设置

# 创建 response 对象 response = HttpResponse() # 调用对象的 set_cookie() 函数 response.set_cookie(key, value, max_age) key: cookie 中保存信息的名称value: cookie 中保存信息时, 名称对应的值部分max_age: cookie 中保存信息的有效期, 超过有效期, key-value 失效, max_age 单位为秒, 默认为 None. 如果设置 None 值, 则关闭浏览器失效.

3.4.2 使用

返回的对象为字典对象

value = request.COOKIES.get('key')

3.5 Session

默认启动Session,如需关闭到settings.py下的MIDDLEWARE注释’django.contrib.sessions.middleware.SessionMiddleware’

3.5.1 储存位置配置

3.5.1.1 数据库

1、添加设置:

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

2、在INSTALLED_APPS 中添加Session:

3.5.1.2 本地缓存

添加设置:

SESSION_ENGINE='django.contrib.sessions.backends.cache'
3.5.1.3 混合缓存

先查本地再查数据库。 添加设置:

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

3.5.2 操作

# 写入数据 request.session[key] = value # 读取数据 value = request.session.get(key, default=None) # 清除全部值 request.session.clear() # 清除session对象 request.session.flush() # 删除指定键值对 del request.session['键'] # 设置session有效期 request.session.set_expiry(value) # value是正整数:在 value 秒没有活动后过期 # value是0:将在用户的浏览器关闭时过期 # value是None:有效期将采用系统默认值,默认为两周,可以通过在 settings.py 中设置 SESSION_COOKIE_AGE 来设置全局默认值

4 视图

视图分为函数写的函数视图,类写的类视图

4.1 视图配置

函数视图在上面2.4有详细配置,类视图如下:

# 类视图定义,于子路由的views.py文件中 class RegisterView(View): """类视图:处理注册""" def get(self, request): """处理 GET 请求,返回注册页面""" print('RegisterView get') return HttpResponse('RegisterView get方法') def post(self, request): """处理 POST 请求,实现注册逻辑""" print('RegisterView post') return HttpResponse('RegisterView post方法') # 在主路由urls.py文件的urlpatterns添加如下 url(r'^register/$', views.RegisterView.as_view()), # 在后面添加as_view()可以让程序自动识别网站的访问方式,如get、post等,要求在类视图定义时要将内部的函数命名为规定名字。

4.2 视图配置

4.2.1 路由中添加

url(r'^register/$', 修饰器名(views.RegisterView.as_view())),

4.2.2 类中直接添加

from django.utils.decorators import method_decorator # 自己添加的修饰器需引入新内容 class RegisterView(View): @method_decorator(修饰器名) def get(self, request): pass

4.3 Mixin扩展类

提供方便的视图操作,参考 。 使用上直接在类视图定义内添加父继承:

class DemoView(添加的扩展名1, 添加的扩展名2, View):

4.4 中间件

在视图的调用前后被使用一次

# 在子应用下新建文件middleware.py输入 def my_middleware(get_response): print('init 被调用') def middleware(request): print('before request 被调用') response = get_response(request) print('after response 被调用') return response return middleware # 在setting.py文件下的MIDDLEWARE新添项 'demo_1.middleware.my_middleware', # 使用时修改demo_1为自己的子应用名

接着在调用视图时就会自动运行中间件的信息,多个中间件时运行顺序是视图被处理前是按MIDDLEWARE中的顺序从前到后,视图处理后相反。

5 模板

5.1 模板路径配置及使用

在setting.py文件下的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', ], }, }, ]

需要新增一个存放模板的文件夹于工程根目录下,存放的模板文件为.html文件。例如新建文件index.html:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!--模板中可以定义变量--> <h1>{{city}}</h1> <h2>{{aaa}}</h2> </body> </html>

接着在文件views.py编写视图函数调用模板:

def demo_model(request): # 定义一个变量, 拼接为字典格式: context={'city': '北京', 'aaa': 'title'} # 返回 render() 函数 return render(request,'index.html',context)

6 数据库

6.1 配置

1、打开在工程文件根目录下与工程同名的子文件夹内的__init__.py文件,在里面添加:

from pymysql import install_as_MySQLdb # 调用函数 install_as_MySQLdb()

2、将setting.py文件内的DATABASES修改为如下内容:

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'HOST': '127.0.0.1', # 数据库主机 'PORT': 3306, # 数据库端口 'USER': 'root', # 数据库用户名 'PASSWORD': 'your_password', # 数据库用户密码 'NAME': 'django_demo' # 数据库名字 } }

根据自己mysql数据库的设置进行填充和修改。 3、使用mysql新建数据库,数据库名字要求与上面名字一致:

create database django_demo default charset=utf8;

4、正常运行。

6.2 模型类

必须继承django.db.models的Model

from django.db import models # 定义图书模型类 BookInfo class BookInfo(models.Model): btitle = models.CharField(max_length=20, verbose_name='名称') bpub_date = models.DateField(verbose_name='发布日期') bread = models.IntegerField(default=0, verbose_name='阅读量') bcomment = models.IntegerField(default=0, verbose_name='评论量') is_delete = models.BooleanField(default=False, verbose_name='逻辑删除') class Meta: db_table = 'tb_books' # 指明数据库表名 verbose_name = '图书' # 在admin站点中显示的名称 verbose_name_plural = verbose_name # 显示的复数名称 def __str__(self): """定义每个数据对象的显示信息""" return self.btitle

6.2.1 数据类型

定义表格每列的数据类型

:类型::说明:AutoField自动增长的IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性BooleanField布尔字段,值为True或FalseNullBooleanField支持Null、True、False三种值CharField字符串,参数max_length表示最大字符个数TextField大文本字段,一般超过4000个字符时使用IntegerField整数DecimalField十进制浮点数, 参数max_digits表示总位数, 参数decimal_places表示小数位数FloatField浮点数DateField日期, 参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为False; 参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为False; 参数auto_now_add和auto_now是相互排斥的,组合将会发生错误TimeField时间,参数同DateFieldDateTimeField日期时间,参数同DateFieldFileField上传文件字段ImageField继承于FileField,对上传的内容进行校验,确保是有效的图片

6.2.2 参数

定义表格每列的相关参数

参数说明null如果为True,表示允许为空,默认值是Falseblank如果为True,则该字段允许为空白,默认值是Falsedb_column字段的名称,如果未指定,则使用属性的名称db_index若值为True, 则在表中会为此字段创建索引,默认值是Falsedefault默认primary_key若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用unique如果为True, 这个字段在表中必须有唯一值,默认值是Falserelated_name在关联查询中,代替单一对象查找多对象 对象名小写_set(book.heroinfo_set.all() 的写法auto_now_add只在数据添加的时候,记录时间auto_now数据添加和更新的时候,记录时间

6.2.3 数据同步

# 生成迁移文件 python manage.py makemigrations # 同步到数据库 python manage.py migrate

6.2.4 数据更新

6.2.4.1 增删改
# 1 增加 # save 对象名 = 模型类(添加数据(id=1,name='www')) 对象名.save() # create 模型类.objects.create(添加数据(id=1,name='www')) # 2 删除 # 对象删除 对象 = 模型类.objects.get(查询条件(id=3)) 对象.delete() # 查询集删除,与python操作mysql的方法类似 模型类.objects.filter(查询条件(id=3)).delete() # 3 修改 # save 对象 = 模型类.objects.get(查询条件(如name='3')) 对象.name = '4' 对象.save() # update,与python操作mysql的方法类似 模型类.objects.filter(查询条件(如name='3')).update(修改结果(如name='4'))
6.2.4.2 查询
基本查询 # get 查询单一结果,如果不存在会抛出 模型类.DoesNotExist 异常. 模型类.objects.get(查询条件(如name='3')) # all 查询多个结果。 模型类.objects.all() # count 查询结果数量。 BookInfo.objects.count(查询条件) 过滤查询 # 属性名称__比较运算符 = 值 模型类.objects.filter(id__exact=1) 运算符说明示例exact表示判等id__exact=1contains是否包含name__contains=‘a’startswith以指定值开头name__startswith=‘a’endswith以指定值结尾name__endswith=‘d’isnull是否为nullname=Falsein是否包含在范围内id__in=[1,2,3]gt大于 (greater then)id__gt=3gte大于等于 (greater then equal)id__gte=3lt小于 (less then)id__lt=3lte小于等于 (less then equal)id__lte=3year、month、day、week_day、hour、minute、second对日期时间类型的属性进行运算date__year=1980(年份是1980),date__gt=date(1990, 1, 1)(时间大于1990/1/1) 跨列查询

使用 django.db.models的F方法

模型类.objects.filter(列1__运算符=F('列2')) 多条件查询(与、或)

使用 django.db.models的Q方法

模型类.objects.filter(Q(条件1) | Q(条件2)) 模型类.objects.filter(~Q(条件)) # 不满足条件的所有 聚合查询

除Count 外使用 aggregate( ) 过滤器调用聚合函数聚合函数被定义在 django.db.models 中,Avg 平均,Count 数量,Max 最大,Min 最小,Sum 求和。返回:字典: {‘属性名__聚合类小写’:值}

模型类.objects.aggregate(聚合函数('列')) 模型类.objects.count() 排序 模型类.objects.all().order_by('列') # 升序 模型类.objects.all().order_by('-列') # 降序 # 区别在于列名前是否加-

关联查询,参考

查询集 ( QuerySet )

过滤器可以连续使用,如BookInfo.objects.filter(bread__gt=30).order_by(‘bpub_date’)

过滤器解释all( )返回所有数据。filter( )返回满足条件的数据。exclude( )返回满足条件之外的数据。order_by( )对结果进行排序。
最新回复(0)