一、WSGI接口
WSGI服务网关接口:Web Server Gateway Interface缩写。
WSGI是python定义的Web服务器和Web应用程序之间或框架之间的通用接口标准。
WSGI定义:Web开发者实现了一个函数,并响应HTTP请求。
WSGI将Web组件分成三类:Web服务器(WSGI Server),Web中间件(WSGI Middleware),Web用用程序(WSGI Application).
Web服务器接收HTTP请求,调用WSGI接口标准注册的WSGI Application,最后将响应返回给客户端。
Web应用的本质:1.浏览器发送HTTP请求。
2.服务器接收请求,生成HTML页面。
3.服务器将HTML页面当成HTTP响应的body发送给浏览器。
4.浏览器接收到HTTP响应,并从HTTP Body中HTML并渲染出来
二、中间件
django的中间件(Middleware),其实就是一个类,在请求前和请求后,django会根据自己的规则并在合适的时机执行中间件中相应的方法。
中间件的官方说法是中间件是一个用来处理django的请求和相应的框架级别的钩子。在全局范围内改变django的输入和输出,每个中间件都有特定的功能。
中间件可以定义五个方法:1.process_request(self, request)
2.process_response(self, request, response)
3.process_view(self, request, view_func, view_args, view_kwargs)
4.process_exception(self, request, exception)
5.process_template_response(self, request, response)
以上方法返回的可以是None也可以是HttpResponse对象,如果是None,这继续按照django的规则继续执行下面的中间件,如果是HttpResponse对象,则直接把对象返回给用户。
process_request
process_request有一个参数,就是request,这个request和视图函数中的request是一样的。它的返回值可以是None也可以是HttpResponse对象。返回值是None的话,按正常流程继续走,交给下一个中间件处理,如果是HttpResponse对象,Django将不执行视图函数,而是直接走本中间件的process_response方法,倒序返回,将相应对象返回给浏览器。
- 中间件的process_request方法是在执行视图函数之前执行的。
- 当配置多个中间件时,会按照MIDDLEWARE中的注册顺序,也就是列表的索引值,从前到后依次执行的。
- 不同中间件之间传递的request都是同一个对象
process_response
process_response有两个参数,一个是request,一个是response。这里面的request和process_request里面的参数request是一样的对象,response是视图函数返给回给用户的是Httpresponse对象,并且该方法返回值必须是HttpResponse对象。
- 中间件的process_response方法是在执行视图函数之后执行的。
- 当配置多个中间件时,会按照MIddleware注册顺序的倒序执行,从后往前执行。
process_view
process_view有四个参数:1.request是HttpResponse对象
2.view_func是django即将用到的视图函数,它是实际的视图函数
3.view_args是传递给视图函数的位置参数的列表
4.view_kwargs是传递给视图函数的关键之参数的字典
5.args和kwargs都不包含第一个参数request
- 中间件的process_view方法是在执行视图函数之前执行的。
- process_view方法是在所有的process_request方法执行完之后执行的
- 当配置多个中间件时,会按照Middleware的注册顺序从前往后执行
process_view它应该返回一个None或HttpResponse对象,如果返回None,则继续执行剩下的中间件的process_view方法,然后再执行相应的视图。如果返回HttpResponse对象,则不再执行剩下的process_view和后面的视图函数,它将执行中间件的process_response方法并将应用到HttpResponse并返回结果。
process_exception
process_exception有两个参数:request是一个HttpResponse对象,exception是视图产生的Exception对象。这个方法是只有视图函数执行异常时才执行的,它返回的对象可以是一个None也可以是一个HttpResponse对象。如果是HttpResponse对象,django将调用模板和process_response方法并返回给浏览器。,否则默认处理异常。
- 如果视图函数中无异常,process_exception方法则不执行。
- 当配置多个中间件时,会按照Middleware的注册顺序从后往前执行
- 当一个中间的process_exception方法执行了,则直接调用process_response方法,不再执行其他中间件的process_exception方法
process_template_response
它有两个参数,request参数是HttpResponse对象,response参数是TemplateResponse对象(由视图函数或中间件产生)。
- process_template_response方法是在视图函数之后立即执行
- 但是它由一个前提条件,就是视图函数返回的对象有一个render()(或则表明表明该对象是一个TemplateResponse对象或等价方法)
- 当配置多个中间件时,会按照Middleware的注册顺序从后往前执行
- 然后执行视图函数返回的HttpResponse对戏那个的render()方法,并返回一个新的HttpResponse对象
- 然后执行process_response方法
三、URL路由系统(URLconf)
URL配置(URLconf)就像django所支撑网站的目录,它的本质就是该URL和要为该URL调用的视图函数之间的映射表。
# 基本配置
from djago.conf.urls import url urlpattrens = [
url(正则表达式,views视图函数名,参数,别名),
]
# 注意事项
1.从上到下一次匹配,一旦匹配成功就不再匹配
2.不需要添加一个前导的斜杠,因为每个URL都有
3.每个正则表达式前的r是可选的,但建议加上
# 补充说明
APPEEND_SLASH = True # django默认为True,作用就是自动在网址末尾加/
- URLconf不检验请求方法,同一个URL不论什么请求方式,都走同一个视图函数。
- 捕捉到的参数永远都是字符串
# 起别名
url(r'^home', views.home, name='home'), # 给我的url匹配模式起名为 home
url(r'^index/(\d*)', views.index, name='index'), # 给我的url匹配模式起名为index
这样:
在模板里面可以这样引用:
{% url 'home' %}
在views函数中可以这样引用:
from django.urls import reverse reverse("index", args=("2018", ))
命名空间模式
即使不同的APP使用相同的URL名称,URL的命名空间模式也可以让你唯一反转命名的URL。
举个例子:
project中的urls.py
from django.conf.urls import url, include urlpatterns = [
url(r'^app01/', include('app01.urls', namespace='app01')),
url(r'^app02/', include('app02.urls', namespace='app02')),
]
app01中的urls.py
from django.conf.urls import url
from app01 import views app_name = 'app01'
urlpatterns = [
url(r'^(?P<pk>\d+)/$', views.detail, name='detail')
]
app02中的urls.py
from django.conf.urls import url
from app02 import views app_name = 'app02'
urlpatterns = [
url(r'^(?P<pk>\d+)/$', views.detail, name='detail')
]
现在,我的两个app中 url名称重复了,我反转URL的时候就可以通过命名空间的名称得到我当前的URL。
语法:
'命名空间名称:URL名称'
模板中使用:
{% url 'app01:detail' pk=12 pp=99 %}
views中的函数中使用
v = reverse('app01:detail', kwargs={'pk':11})
这样即使app中URL的命名相同,我也可以反转得到正确的URL了。
有名分组
# 这种形式是无名分组
from django.conf.urls import url from . import views urlpatterns = [
url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/([0-9]{4})/$', views.year_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]
没有命名的正则表达式组(通过圆括号)来捕获URL中的值并以位置参数传递给视图。在更高级的用法中,可以使用命名的正则表达式组来捕获URL 中的值并以关键字 参数传递给视图。
在Python 正则表达式中,命名正则表达式组的语法是(?P<name>pattern)
,其中name
是组的名称,pattern
是要匹配的模式。
from django.conf.urls import url from . import views urlpatterns = [
url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
]
这个实现与无名分组完全相同,只有一个细微的差别:捕获的值作为关键字参数而不是位置参数传递给视图函数。例如:
/articles/2005/03/
请求将调用views.month_archive(request, year='', month='')函数
/articles/2003/03/03/
请求将调用函数views.article_detail(request, year='', month='', day='')。
四、Template模板
python的模板:HTML代码+逻辑控制代码
# 变量 用双大括号来引用变量 用法:{{ title }}
# 逻辑 用大括号和百分号组合 用法:{% for user in user_list %} {% endfor %}
# 点 . 在模板里面有特殊的含义,就是获取对象的相应属性值 {{ user.name }}
# 模板中支持的写法
{# 取l中的第一个参数 #}
{{ l.0 }}
{# 取字典中key的值 #}
{{ d.name }}
{# 取对象的name属性 #}
{{ person_list.0.name }}
{# .操作只能调用不带参数的方法 #}
{{ person_list.0.dream }}
Filters过滤器的使用
语法: {{ value|filter_name:参数 }}
{{ value|default:"nothing" }}
{{ value|length }} # 返回value的长度
{{ value|filesizeformat }} # 将十进制数转为为KB,MB,GB等
{{ value|slice:"2:-1" }} # 切片
{{ value|data:"Y-m-d H:i:s" }} # 格式化时间
{{ value|safa }} # 告诉django这段代码是安全的,不必转译
{{ value|truncatechars:9 }} # 截断,如果value的字符数大于9,则只显示前9个字符,后面的用...表示。
{{ value|upper }} # 将value的字母全变成大写
{{ value|add:2 }} # value值+2并显示
{{ value|cut:"a" }} # 移除指定字符
自定义filter过滤器
from django import template
register = template.Library() @register.filter(name="cut")
def cut(value, args):
return value.replace(args, "") @register.filter(name="add")
def add(value):
return "{}很可爱!".format(value)
{# 先导入我们自定义filter那个文件 #}
{% load app01_filters %} {# 使用我们自定义的filter #}
{{ somevariable|cut:"" }}
{{ value|add }}
注意:以上代码要在django项目中使用
前端未完待续......
五、Views视图
django的两种处理请求的方式:FBV和CBV
FBV:function base views 在视图里面基于函数处理请求
CBV:class base views 在视图里面基于类处理请求
# urls.py中
url(r'^add_class/$', views.AddClass.as_view()),
Response对象
HttpResponse类位于django.http模块中。
使用
传递字符串
from django.http import HttpResponse
response = HttpResponse("Here's the text of the Web page.")
response = HttpResponse("Text only, please.", content_type="text/plain")
设置或删除响应头信息
response = HttpResponse()
response['Content-Type'] = 'text/html; charset=UTF-8'
del response['Content-Type']
属性
HttpResponse.content:响应内容
HttpResponse.charset:响应内容的编码
HttpResponse.status_code:响应的状态码
JsonResponse对象
JsonResponse是HttpResponse的子类,专门用来生成JSON编码的响应。
from django.http import JsonResponse response = JsonResponse({'foo': 'bar'})
print(response.content) b'{"foo": "bar"}'
默认只能传递字典类型,如果要传递非字典类型需要设置一下safe关键字参数。
response = JsonResponse([1, 2, 3], safe=False)
render()
结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。
from django.shortcuts import render def my_view(request):
# 视图的代码写在这里
return render(request, 'myapp/index.html', {'foo': 'bar'})
redirect()
参数可以是:
- 一个模型:将调用模型的get_absolute_url() 函数
- 一个视图,可以带有参数:将使用urlresolvers.reverse 来反向解析名称
- 一个绝对的或相对的URL,将原封不动的作为重定向的位置。
默认返回一个临时的重定向;传递permanent=True 可以返回一个永久的重定向。
示例:
你可以用多种方式使用redirect() 函数。
传递一个具体的ORM对象(了解即可)
将调用具体ORM对象的get_absolute_url() 方法来获取重定向的URL:
from django.shortcuts import redirect def my_view(request):
...
object = MyModel.objects.get(...)
return redirect(object)
传递一个视图的名称
def my_view(request):
...
return redirect('some-view-name', foo='bar')
传递要重定向到的一个具体的网址
def my_view(request):
...
return redirect('/some/url/')
当然也可以是一个完整的网址
def my_view(request):
...
return redirect('http://example.com/')
默认情况下,redirect() 返回一个临时重定向。以上所有的形式都接收一个permanent 参数;如果设置为True,将返回一个永久的重定向:
def my_view(request):
...
object = MyModel.objects.get(...)
return redirect(object, permanent=True)
扩展阅读:
临时重定向(响应状态码:302)和永久重定向(响应状态码:301)对普通用户来说是没什么区别的,它主要面向的是搜索引擎的机器人。
A页面临时重定向到B页面,那搜索引擎收录的就是A页面。
A页面永久重定向到B页面,那搜索引擎收录的就是B页面。
6.2、操作表
基本操作
# 增
#
# models.Tb1.objects.create(c1='xx', c2='oo') 增加一条数据,可以接受字典类型数据 **kwargs # obj = models.Tb1(c1='xx', c2='oo')
# obj.save() # 查
#
# models.Tb1.objects.get(id=123) # 获取单条数据,不存在则报错(不建议)
# models.Tb1.objects.all() # 获取全部
# models.Tb1.objects.filter(name='seven') # 获取指定条件的数据 # 删
#
# models.Tb1.objects.filter(name='seven').delete() # 删除指定条件的数据 # 改
# models.Tb1.objects.filter(name='seven').update(gender='0') # 将指定条件的数据更新,均支持 **kwargs
# obj = models.Tb1.objects.get(id=1)
# obj.c1 = '111'
# obj.save() # 修改单条数据
# save是更改所有字段,即使更改一个字段,也会将所有字段重新赋值, 不推荐
# update更改,只更改修改的字段,推荐使用 # update方式修改不能用get的原因是:update是QuerySet对象的方法,get返回的是一个model对象,它没有update方法,而filter返回的是一个QuerySet对象(filter里面的条件可能有多个条件符合,比如name='alvin',可能有两个name='alvin'的行数据) 基本操作
基本操作
查询相关API
# 查询相关API: # <1>filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 # <2>all(): 查询所有结果 # <3>get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。 #-----------下面的方法都是对查询的结果再进行处理:比如 objects.filter.values()-------- # <4>values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model的实例化对象,而是一个可迭代的字典序列 # <5>exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象 # <6>order_by(*field): 对查询结果排序 # <7>reverse(): 对查询结果反向排序 # <8>distinct(): 从返回结果中剔除重复纪录 # <9>values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列 # <10>count(): 返回数据库中匹配查询(QuerySet)的对象数量。 # <11>first(): 返回第一条记录 # <12>last(): 返回最后一条记录 # <13>exists(): 如果QuerySet包含数据,就返回True,否则返回False 查询相关API
查询API
进阶操作(了不起的双下划线)
# 获取个数
#
# models.Tb1.objects.filter(name='seven').count() # 大于,小于
#
# models.Tb1.objects.filter(id__gt=1) # 获取id大于1的值
# models.Tb1.objects.filter(id__gte=1) # 获取id大于等于1的值
# models.Tb1.objects.filter(id__lt=10) # 获取id小于10的值
# models.Tb1.objects.filter(id__lte=10) # 获取id小于10的值
# models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值 # in
#
# models.Tb1.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据
# models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in # isnull
# Entry.objects.filter(pub_date__isnull=True) # contains
#
# models.Tb1.objects.filter(name__contains="ven")
# models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
# models.Tb1.objects.exclude(name__icontains="ven") # range
#
# models.Tb1.objects.filter(id__range=[1, 2]) # 范围bettwen and # 其他类似
#
# startswith,istartswith, endswith, iendswith, # order by
#
# models.Tb1.objects.filter(name='seven').order_by('id') # asc
# models.Tb1.objects.filter(name='seven').order_by('-id') # desc # group by
#
# from django.db.models import Count, Min, Max, Sum
# models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
# SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id" # limit 、offset
#
# models.Tb1.objects.all()[10:20] # regex正则匹配,iregex 不区分大小写
#
# Entry.objects.get(title__regex=r'^(An?|The) +')
# Entry.objects.get(title__iregex=r'^(an?|the) +') # date
#
# Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
# Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1)) # year
#
# Entry.objects.filter(pub_date__year=2005)
# Entry.objects.filter(pub_date__year__gte=2005) # month
#
# Entry.objects.filter(pub_date__month=12)
# Entry.objects.filter(pub_date__month__gte=6) # day
#
# Entry.objects.filter(pub_date__day=3)
# Entry.objects.filter(pub_date__day__gte=3) # week_day
#
# Entry.objects.filter(pub_date__week_day=2)
# Entry.objects.filter(pub_date__week_day__gte=2) # hour
#
# Event.objects.filter(timestamp__hour=23)
# Event.objects.filter(time__hour=5)
# Event.objects.filter(timestamp__hour__gte=12) # minute
#
# Event.objects.filter(timestamp__minute=29)
# Event.objects.filter(time__minute=46)
# Event.objects.filter(timestamp__minute__gte=29) # second
#
# Event.objects.filter(timestamp__second=31)
# Event.objects.filter(time__second=2)
# Event.objects.filter(timestamp__second__gte=31) 进阶操作
双下方法
连表操作(了不起的双下划线)
利用双下划线和 _set 将表之间的操作连接起来
class UserProfile(models.Model):
user_info = models.OneToOneField('UserInfo')
username = models.CharField(max_length=64)
password = models.CharField(max_length=64) def __unicode__(self):
return self.username class UserInfo(models.Model):
user_type_choice = (
(0, u'普通用户'),
(1, u'高级用户'),
)
user_type = models.IntegerField(choices=user_type_choice)
name = models.CharField(max_length=32)
email = models.CharField(max_length=32)
address = models.CharField(max_length=128) def __unicode__(self):
return self.name class UserGroup(models.Model): caption = models.CharField(max_length=64) user_info = models.ManyToManyField('UserInfo') def __unicode__(self):
return self.caption class Host(models.Model):
hostname = models.CharField(max_length=64)
ip = models.GenericIPAddressField()
user_group = models.ForeignKey('UserGroup') def __unicode__(self):
return self.hostname 表结构实例
表结构
user_info_obj = models.UserInfo.objects.filter(id=1).first()
print(user_info_obj.user_type)
print(user_info_obj.get_user_type_display())
print(user_info_obj.userprofile.password) user_info_obj = models.UserInfo.objects.filter(id=1).values('email', 'userprofile__username').first()
print(user_info_obj.keys())
print(user_info_obj.values())
OneToOne
Django框架详解的更多相关文章
-
Django框架详解之url
Django基本命令 下载Django pip3 install django 创建一个django project django-admin.py startproject cms 当前目录下会生成 ...
-
Django框架详解之template
模板简介 将页面的设计和python的代码分离开会更干净简洁更容易维护.我们可以使用Django的模板系统来实现这种模式 python的模板:HTML代码+模板语法 模板包括在使用时会被值替换掉的变量 ...
-
Django框架详解之views
一个简单的视图 一个视图函数,是一个简单的python函数,它接受web请求并且返回web响应.无论视图本身包含什么逻辑,都要返回响应.为了将代码放在某处,约定是将视图放置在项目或应用程序目录中的名为 ...
-
Django 2.0 学习(20):Django 中间件详解
Django 中间件详解 Django中间件 在Django中,中间件(middleware)其实就是一个类,在请求到来和结束后,Django会根据自己的规则在合适的时机执行中间件中相应的方法. 1. ...
-
jQuery Validate验证框架详解
转自:http://www.cnblogs.com/linjiqin/p/3431835.html jQuery校验官网地址:http://bassistance.de/jquery-plugins/ ...
-
mina框架详解
转:http://blog.csdn.net/w13770269691/article/details/8614584 mina框架详解 分类: web2013-02-26 17:13 12651人 ...
-
lombok+slf4j+logback SLF4J和Logback日志框架详解
maven 包依赖 <dependency> <groupId>org.projectlombok</groupId> <artifactId>lomb ...
-
[Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解
Core data 是 Cocoa 中处理数据,绑定数据的关键特性,其重要性不言而喻,但也比较复杂.Core Data 相关的类比较多,初学者往往不太容易弄懂.计划用三个教程来讲解这一部分: 框架详解 ...
-
iOS 开发之照片框架详解(2)
一. 概况 本文接着 iOS 开发之照片框架详解,侧重介绍在前文中简单介绍过的 PhotoKit 及其与 ALAssetLibrary 的差异,以及如何基于 PhotoKit 与 AlAssetLib ...
随机推荐
-
[转]ASP.NET 成员资格 Part.1(API)
本文转自:http://www.cnblogs.com/SkySoot/archive/2013/04/08/3008418.html 表单验证解决了 ASP.NET 应用程序页面验证的问题,但另一方 ...
-
AngularJS Filters
过滤器可以使用一个管道字符(|)添加到表达式和指令中. AngularJS 过滤器 AngularJS 过滤器可用于转换数据: 过滤器 描述 currency 格式化数字为货币格式. filter 从 ...
-
ASP.NET中获取当日,当周,当月,当年的日期
ASP.NET中获取当日,当周,当月,当年的日期 在ASP.NET开发中,经常会碰到要获取当日,当周,当月,当年的日期. 以下将源码贴出来和大家分享. aspx中代码如下: <table ce ...
-
[原创] zabbix学习之旅四:mail客户端安装
相信大家使用zabbix的最主要目的就是当被监控机器发生故障时,能通过zabbix获得第一时间的报警提醒.zabbix常用的报警媒介有email,短信,jabber和脚本,这其中脚本类型最为灵活,尤其 ...
-
Oracle DBA 的常用Unix参考手册(一)
作为一名Oracle DBA,在所难免要接触Unix,但是Unix本身又是极其复杂的,想要深刻掌握同样很不容易.那么到底我们该怎么入手呢?Donald K Burleson 的<Unix for ...
-
git cannot lock ref
参考博客:https://blog.csdn.net/lindexi_gd/article/details/79213042 错误原文: cannot lock ref ‘refs/remotes/o ...
-
Jsの练习-数组常用方法
1. join() 方法: <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...
-
#leetcode刷题之路42-接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水.上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 ...
-
python基础===对字符串进行左右中对齐
例如,有一个字典如下: >>> dic = { "name": "botoo", "url": "http:// ...
-
MySQL数据库(2)- 库的操作、表的操作、数据的操作、存储引擎的介绍
一.库的操作 1.系统数据库 执行如下命令,查看系统数据库: mysql> show databases; 参数解释: information_schema: 虚拟库,不占用磁盘空间,存储的是数 ...