本节内容:
1、Django简单示例
2、MTV之url控制器
3、MTV之视图函数
4、MTV之模板
一、Django的简单示例
1、需要知道的一些关键点
1 Django项目无论多大,只是一个应用程序
2 地址栏发请求默认是:1、GET请求
2、form表单可以发送get请求,也可以发送post请求
3、
标签也可以发送请求
3 浏览器接受的响应体是字符串,由浏览器解释渲染成页面给用户看
4 form表单的提交按钮事件:
给action对应的服务器发送请求
''
GET /auth/?数据user=yuan&pwd=123 ....
......
......
空行
请求体 # user=yuan&pwd=123
''
5 新的响应会覆盖之前请求的响应页面
2、Django的简单示例
写代码的顺序就按文件的顺序
urls.py代码
from django.contrib import admin
from django.urls import path,re_path
from app01 import views # 引入视图模块
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
path('login/', views.login),
]
PythonCopy
views.py代码示例
from django.shortcuts import render,HttpResponse,redirect # 响应体三剑客
# Create your views here.
def login(request):
if request.method=="GET":
return render(request,"login.html")
else:
# request :包含所有请求信息
# 获取请求信息
print("body", request.body) # 请求体原生数据
print(request.method) # "POST" 请求方式
print(request.path) # "/auth/" 拿到路径
print(request.GET) #
print(request.POST) #
user = request.POST.get("user")
pwd = request.POST.get("pwd")
print("user", user)
if user == "alex" and pwd == "123":
return redirect("/index/") # 这样这里写死了代码
return HttpResponse("Error!")
PythonCopy
login.html代码示例
Title
HTMLCopy
二、路由控制器
本质是URL与要为该URL调用的视图函数之间的映射表,就是以这种方式告诉Django,
对于客户端发来的某个URL调用哪一段逻辑代码对应执行。
(这里注意使用反向解析,可以实现动态修改访问路径)
这里的执行顺序:
1、拿着path(路径:IP地址或域名,之后的,?号之前的,这中间这一截,/index/),
2、在urls.py的urlpatterns的列表中进行比对,比对成功
3、执行对应的视图函数,
4、视图函数返回响应给浏览器
1、简单的使用
相应代码示例
urls.py文件
from django.urls import path,re_path
from app01 import views
urlpatterns = [
# 从上往下匹配,(前后条件都可以匹配成功的话)如果前面的先匹配,后面的就不会再匹配,
re_path(r'^articles/2003/$', views.special_case_2003), # special_case_2003(request)
re_path(r'^articles/([0-9]{4})/$', views.year_archive), # year_archive(request,1999)
re_path(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
re_path(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]
相应的解释:
/articles/2005/03/ 请求将匹配列表中的第三个模式。Django 将调用函数views.month_archive(request, '2005', '03')。
/articles/2005/3/ 不匹配任何URL 模式,因为列表中的第三个模式要求月份应该是两个数字。
/articles/2003/ 将匹配列表中的第一个模式不是第二个,因为模式按顺序匹配,第一个会首先测试是否匹配。
请像这样自由插入一些特殊的情况来探测匹配的次序。
/articles/2003 不匹配任何一个模式,因为每个模式要求URL 以一个反斜线结尾。
/articles/2003/03/03/ 将匹配最后一个模式。Django 将调用函数views.article_detail(request, '2003', '03', '03')。
PythonCopy
注意:
1、若要从URL 中捕获一个值,只需要在它周围放置一对圆括号。
2、不需要添加一个前导的反斜杠,因为每个URL 都有。
例如,应该是^articles 而不是 ^/articles。
3、每个正则表达式前面的'r' 是可选的但是建议加上。
它告诉Python 这个字符串是“原始的” —— 字符串中任何字符都不应该转义
2、分组(目的:传参给view函数)
上面的示例使用简单的、没有命名的正则表达式组(通过圆括号)
来捕获URL 中的值并以位置 参数传递给视图。
在更高级的用法中,可以使用命名的正则表达式组来捕获URL 中的值并以关键字 参数传递给视图。
在Python 正则表达式中,(这个是1版本的写法,2版本默认有首尾的正则限定,不用写)
命名正则表达式组的语法是(?Ppattern),
其中name 是组的名称,pattern 是要匹配的模式
fe:命名分组的写法
下面是以URLconf 使用命名组的重写:
urls.py文件
from django.urls import path,re_path
from app01 import views
urlpatterns = [
re_path(r'^articles/2003/$', views.special_case_2003),
re_path(r'^articles/(?P[0-9]{4})/$', views.year_archive),
re_path(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})/$', views.month_archive),
re_path(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})/(?P[0-9]{2})/$', views.article_detail),
]
这个实现与前面的示例完全相同,只有一个细微的差别:
捕获的值作为关键字参数而不是位置参数传递给视图函数。例如:
详细解释:
/articles/2005/03/ 请求将调用views.month_archive(request, year='2005', month='03')函数,
而不是views.month_archive(request, '2005', '03')。
/articles/2003/03/03/ 请求将调用函数views.article_detail(request, year='2003', month='03', day='03')。
在实际应用中,这意味你的URLconf 会更加明晰且不容易产生参数顺序问题的错误 ——
你可以在你的视图函数定义中重新安排参数的顺序。当然,这些好处是以简洁为代价;
PythonCopy
3、分发(目的:解耦合)
不是把所有的urls都写在全局的urls.py文件中,
而是在全局的urls.py指向对应的app文件中的urls.py文件中,
在对应的app中做进一步的分发,从而达到了各个app的在全局的urls文件的解耦
# 全局的urls.py文件
urlpatterns = [
path('admin/', admin.site.urls),
# 分发
url('app/', include('app.urls')), # 分发指向具体的app下,达到解耦
url('app02/', include('app02.urls'))
]
# app01下的urls.py
urlpatterns = [
url(r'^articles/2003/$', views.special_case_2003), # special_case_2003(request)
]
# app02下的urls.py
urlpatterns = [
url(r'^videos/(d+)', views.videos), # special_case_2003(request)
]
PythonCopy
4、反向解析
目的:动态的改变path路径,从而避免硬编码这些URL,
直白的说:改变原来的path,就要手动改把所有文件中有关于的这path的名字。
在使用Django 项目时,一个常见的需求是获得URL 的最终形式,
以用于嵌入到生成的内容中(视图中和显示给用户的URL等)或者用于处理服务器端的导航(重定向等)。
1、在需要url的地方,我们第一时间考虑url反查
在需要URL 的地方,对于不同层级,Django 提供不同的工具用于URL 反查:
1、在模板中:使用url 模板标签。
2、在Python 代码中:使用from django.urls import reverse()函数
两种代码及解释示例
urls.py文件
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('home/', views.index,name="index"), # 反向解析,动态的给view函数输入path
path('login.html/', views.login,name="Log"), # 反向解析,动态的给HTML的form表单,输入重写path
]
views.py文件
from django.shortcuts import render,HttpResponse,redirect
# Create your views here.
from django.urls import reverse
def login(request):
_url=reverse("index") # 该命令是是动态的接收反向解析的path
print("_url",_url)
return redirect(_url)
login.html文件
命名url:
不可以跟其他应用中的名称冲突;
在URL 名称中加上一个前缀,比如应用的名称,将减少冲突的可能。
建议使用myapp-comment 而不是comment。
PythonCopy
三、MTV之视图函数(Django的视图层)
一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应。
响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,
或者一张图片. . . 是任何东西都可以。
无论视图本身包含什么逻辑,都要返回响应。
代码写在哪里也无所谓,只要它在你的Python目录下面。
除此之外没有更多的要求了——可以说“没有什么神奇的地方”。
为了将代码放在某处,(所有的视图函数约定放在这个文件下)
约定是将视图放置在项目或应用程序目录中的名为views.py的文件中。
1、视图函数的介绍
视图层,熟练掌握两个对象即可:请求对象(request)和响应对象(HttpResponse)
代码介绍解释
from django.shortcuts import render,HttpResponse,redirect # 响应体三剑客
# Create your views here.
def index(request):
# 响应体:HttpResponse render redirect
# Django响应一定是HttpResponse类对象
#return HttpResponse("INDEX
")
good_list=['小米电视',"海尔冰箱","格力空调","AAA"]
return render(request,"index.html",{"good_list":good_list})
解释:
1、首先,我们从 django.shortcuts模块导入了HttpResponse类,以及Python的datetime库。
2、接着,我们定义了current_datetime函数。它就是视图函数。
每个视图函数都使用HttpRequest对象作为第一个参数,并且通常称之为request。
注意,视图函数的名称并不重要;不需要用一个统一的命名方式来命名,以便让Django识别它。
我们将其命名为current_datetime,是因为这个名称能够精确地反映出它的功能。
3、这个视图会返回一个HttpResponse对象,其中包含生成的响应。
每个视图函数都负责返回一个HttpResponse对象。
PythonCopy
2、HttpRequest对象
1、request属性
django将请求报文中的请求行、首部信息、内容主体封装成 HttpRequest 类中的属性。
除了特殊说明的之外,其他均为只读的。
request详细解释
1.HttpRequest.GET
一个类似于字典的对象,包含 HTTP GET 的所有参数。详情请参考 QueryDict 对象。
2.HttpRequest.POST
一个类似于字典的对象,如果请求中包含表单数据,则将这些数据封装成 QueryDict 对象。
POST 请求可以带有空的 POST 字典 —— 如果通过 HTTP POST 方法发送一个表单,但是表单中没有任何的数据,QueryDict 对象依然会被创建。
因此,不应该使用 if request.POST 来检查使用的是否是POST 方法;应该使用 if request.method == "POST"
另外:如果使用 POST 上传文件的话,文件信息将包含在 FILES 属性中。
注意:键值对的值是多个的时候,比如checkbox类型的input标签,select标签,需要用:
request.POST.getlist("hobby")
3.HttpRequest.body
一个字符串,代表请求报文的主体。在处理非 HTTP 形式的报文时非常有用,例如:二进制图片、XML,Json等。
但是,如果要处理表单数据的时候,推荐还是使用 HttpRequest.POST 。
4.HttpRequest.path
一个字符串,表示请求的路径组件(不含域名)。
例如:"/music/bands/the_beatles/"
5.HttpRequest.method
一个字符串,表示请求使用的HTTP 方法。必须使用大写。
例如:"GET"、"POST"
6.HttpRequest.encoding
一个字符串,表示提交的数据的编码方式(如果为 None 则表示使用 DEFAULT_CHARSET 的设置,默认为 'utf-8')。
这个属性是可写的,你可以修改它来修改访问表单数据使用的编码。
接下来对属性的任何访问(例如从 GET 或 POST 中读取数据)将使用新的 encoding 值。
如果你知道表单数据的编码不是 DEFAULT_CHARSET ,则使用它。
7.HttpRequest.META
一个标准的Python 字典,包含所有的HTTP 首部。具体的头部信息取决于客户端和服务器,下面是一些示例:
CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。
CONTENT_TYPE —— 请求的正文的MIME 类型。
HTTP_ACCEPT —— 响应可接收的Content-Type。
HTTP_ACCEPT_ENCODING —— 响应可接收的编码。
HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。
HTTP_HOST —— 客服端发送的HTTP Host 头部。
HTTP_REFERER —— Referring 页面。
HTTP_USER_AGENT —— 客户端的user-agent 字符串。
QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。
REMOTE_ADDR —— 客户端的IP 地址。
REMOTE_HOST —— 客户端的主机名。
REMOTE_USER —— 服务器认证后的用户。
REQUEST_METHOD —— 一个字符串,例如"GET" 或"POST"。
SERVER_NAME —— 服务器的主机名。
SERVER_PORT —— 服务器的端口(是一个字符串)。
从上面可以看到,除 CONTENT_LENGTH 和 CONTENT_TYPE 之外,请求中的任何 HTTP 首部转换为 META 的键时,
都会将所有字母大写并将连接符替换为下划线最后加上 HTTP_ 前缀。
所以,一个叫做 X-Bender 的头部将转换成 META 中的 HTTP_X_BENDER 键。
8.HttpRequest.FILES
一个类似于字典的对象,包含所有的上传文件信息。
FILES 中的每个键为 中的name,值则为对应的数据。
注意,FILES 只有在请求的方法为POST 且提交的