本文档介绍web框架中Django框架,基于Python。
Uniform Resource Locator,统一资源定位器, URL由三部分组成:资源类型、存放资源的主机域名、资源文件名。 也可认为由4部分组成:协议、主机、端口、路径
URL的一般语法格式为: (带方括号[]的为可选项): protocol : // hostname[:port] / path / [;parameters][?query]#fragment
protocol:协议,如http等。hostname:主机名、IP地址port:端口号path:路径parameters:参数,以?开始到#结束的区域传递参数query:查询fragment:信息片断这是是Django中的字典对象,与Python传统的字典对象不同的是:Python中的字典一个键只能对应一个值,而QueryDict允许一个键对应多个值。
QueryDict.get(key) 获取的是所有值的最后一个,只有一个值时获取当前值QueryDict.getlist(key) 获取这个键对应的所有值, 存放在列表中返回创建工程前应cd至想保持工程的木下
django-admin startproject 工程名称创建目录如下:
___file___ : 当前的文件 os.path.abspath ( 文件 ) : 获取这个文件的绝对路径 os.path.dirname( 路径 ) : 获取这个路径的上一级路径,两次即返回根目录
DEBUG:设置是否为调试模式,默认为True,在True情况下报错会显示具体错误信息。实际对外运行需要设置成False,同时要设置参数ALLOWED_HOSTS,设置允许访问的IP,*为所有。LANGUAGE_CODE:语言,‘zh-hans’ 中文TIME_ZONE:时区,‘Asia/Shanghai’ # 亚洲上海时区切换至创建的过程目录里
python manage.py runserver # 默认127.0.0.1:8000也可以选择在后面选择IP地址和端口默认条件 运行效果在浏览器输入 127.0.0.1:8000
cd至工程文件的根目录下
python manage.py startapp 子应用名称创建的子应用目录
在工程文件里的settings.py文件里的INSTALLED_APPS添加类似“子应用名称.apps.NameConfig”(例’demo_1.apps.Demo1Config’,具体名字根据子应用的名字确定,可以在子应用的apps.py文件查看),如下
打开子应用目录下的views.py编写视图程序
def index(request): return HttpResponse("Hello World!") # 在页面输出Hello World!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/
查询字符是在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进行参数传递: 软件会自动帮助输入调整网址
在基础的视图设置中,我们的路径使用的是完整的路径名,要求完全匹配才能进行访问,而正则化是允许模糊匹配的,因此我们可以利用路径进行传参。
# 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), # 按顺序传参请求体数据格式不固定,可以是表单类型字符串,可以是 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软件传入参数
通过 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使用request.内容来获取,如:request.内容包括:
method:一个字符串,表示请求使用的 HTTP 方法,常用值包+ 括:‘GET’、‘POST’。user:请求的用户对象。path:一个字符串,表示请求的页面的完整路径,不包含域名和参数部分。encoding:一个字符串,表示提交的数据的编码方式。如果为 None 则表示使用浏览器的默认设置,一般为 utf-8。这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下+ + 来对属性的任何访问将使用新的 encoding 值。FILES:一个类似于字典的对象,包含所有的上传文件。用于储存一些用户的默认信息,信息储存于用户的电脑内,实现类似记住用户名之类的效果。
返回的对象为字典对象
value = request.COOKIES.get('key')默认启动Session,如需关闭到settings.py下的MIDDLEWARE注释’django.contrib.sessions.middleware.SessionMiddleware’
1、添加设置:
SESSION_ENGINE='django.contrib.sessions.backends.db'2、在INSTALLED_APPS 中添加Session:
添加设置:
SESSION_ENGINE='django.contrib.sessions.backends.cache'先查本地再查数据库。 添加设置:
SESSION_ENGINE='django.contrib.sessions.backends.cached_db'视图分为函数写的函数视图,类写的类视图
函数视图在上面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等,要求在类视图定义时要将内部的函数命名为规定名字。提供方便的视图操作,参考 。 使用上直接在类视图定义内添加父继承:
class DemoView(添加的扩展名1, 添加的扩展名2, View):在视图的调用前后被使用一次
# 在子应用下新建文件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中的顺序从前到后,视图处理后相反。
在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)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、正常运行。
必须继承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定义表格每列的数据类型
:类型::说明: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,对上传的内容进行校验,确保是有效的图片定义表格每列的相关参数
参数说明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数据添加和更新的时候,记录时间使用 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( )对结果进行排序。