用户在浏览器输入URL发出请求后,Django应用会在路由系统中根据URL查找并运行相应的视图,然后返回信息到浏览器中。
##################################
# ./urls.py #
##################################
from django.contrib import admin
from django.urls import path, include
from app1 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
path('', include('app2.urls'))
]
##################################
# app2/urls.py #
##################################
from django.urls import path
from app2 import views
urlpatterns=[
path('app2/index/', views.index),
path('show//' , views.show),
re_path('app2/page/(?P\d+)&key=(?P\w+)' views.article_page),
path('app2/url_reverse/', views.url_reverse, name='app2_url_reverse'),
]
1)路由基本配置
urls.py
路由配置规则:从上到下匹配urlpatterns列表,如匹配成功,则调用第二个参数指定的视图;如匹配失败,则返回404错误。
2)路由包含
为了降低项目路由(根路由)复杂度,可以在每个应用下单独配置urls.py(子路由)。具体方法是在根路由中使用include()方法加载子路由,如果URL的第一部分匹配,则其余部分在子路由中匹配。
3)解析路由参数
当页面过多,不可能为全部页面都预先配置好路由规则时,引入URL参数进行动态配置,其语法格式为,参数数据类型包括str, int, slug, uuid
| 参数数据类型 | 说明 |
|---|---|
| str | 任意非空字符串,不包含"/" |
| int | 0和正整数 |
| slug | 任意ASCII字符、连接符和下划线 |
| uuid | UUID格式字符串 |
4)正则匹配路由
使用re_path()方法可以使用正则表达式编写URL,语法格式为(?P,其中name是匹配的字符串的名称,pattern是匹配模式。
5)反向解析路由
使用路由配置项命名,使用reverse()方法解析,然后在视图函数或者模板HTML文件中进行调用。这样只有name不变,URL地址可以任意改变。
视图/view层用于处理客户端的请求并生成相应数据。在视图中使用函数处理请求的方式称为视图函数,亦称FBV(Function Base Views),一般放在view.py文件中。
1)底层原理
当浏览器向服务端请求一个页面时,Django先创建一个HttpRequest对象;然后把HttpRequest作为第一个参数传递给相应的视图函数;视图函数会返回一个HttpResponse对象。
from django.http import HttpResponse
def hello(request): #默认接收一个HttpRequest对象作为第一个参数,常用request变量接收此参数
return HttpResponse("Hello there") #返回一个HttpResponse对象,其中包含生成的相应数据
# HttpRequest对象用法示例
def test_get(request):
print(request.get_host()) #域名+端口
print(request.get_raw_uri) #全部路径,含参数
print(request.get_path) #访问文件的路径,不含参数
pritn(request.get_full_path()) #访问文件的路径,含参数
print(request.method) #请求中使用http的方式:POST/GET
print(request.GET) #GET请求的参数
print(request.META["HTTP_USER_AGENT"]) #用户浏览器user-agent
print(request.META["REMOTE_ADDR"]) #客户端IP地址
return HttpResponse("")
def test_post(request):
print(request.method)
print(request.POST.get('username'))
return render(request, '2/test_post.html')
#HttpResponse对象用法示例
def test_response(request):
response = HttpResponse()
response.write("hello dj")
response.write(response.content)
response.write(response['Content-type'])
response.write(response.status_code)
response.write(response.charset)
return response
HttpRequest对象
| 属性/方法 | 类型 | 含义 |
|---|---|---|
| path | 字符串 | 表示请求页面的路径,不包含域名 |
| method | 字符串 | 表示页面的请求方法,如GET, POST等 |
| encoding | 字符串 | 表示提交数据的编码方式,默认UTF-8 |
| GET | 字典类型 | 包含GET请求方法中所有参数 |
| POST | 字典类型 | 包含POST请求方法中所有参数 |
| FILES | 字典类型 | 包含上传文件的信息 |
| COOKIES | 字典类型 | 包含所有Cookies对象 |
| session | 字典类型 | 表示当前的会话 |
| META | 字典类型 | 包含所有HTTP头信息 |
HTTPResponse对象
| 属性 | 含义 |
|---|---|
| content | 返回内容 |
| status_code | 响应状态码 200: 状态成功; 301: 永久重定向; 302: 临时重定向; 404: URL不存在; 500: 内部服务器错误; 502: 网关错误; 503: 服务不可用; |
| content-type | 返回数据的MEME类型,默认为text/html |
视图处理函数
页面渲染:render()函数根据模板文件和传递给模板文件的字典类型的变量,生成一个HttpResponse对象并返回。
from django.shortcuts import render
render(request, template_name, content=None, content_type=None, status=None, using=None)
页面重定向:redirect()函数的参数包含以下3种情况。
# 通过调用模型 get_absolute_url()函数进行重定向
# 通过路由反向解析进行重定向
# 通过一个绝对或相对的的URL,让浏览器跳转到指定的URL进行重定向
使用类处理用户请求的方式,称为视图类(class based views, CBV)。下面示例了3个常用的视图类。
from django.shortcuts import render
from django.http import HttpResponse
from django.view.generic import TemplateView
# TemplateView
class TestTemplateView(TemplateView):
template_name="2/test_templateview.html"
def get_context_data(self, **kwargs):
context=super().get_context_data(**kwargs)
context["info"]="A variable pass to template"
return context
# ListView
# DetailView
模板/template技术主要用于页面展现。Django模板是一种带有DTL的HTML文件,该文件可以被Django编译,其中可以传递参数,以实现数据动态化,最终发送给客户端浏览器。
1)模板变量
模板变量相当于HTML文件中的占位符,可以是字符串、列表、字典或类对象。使用{{ variable_name }}来表示。
# views.py
def var(request):
lists = ['python', 'R', 'perl']
dicts = {'k1':'v1', 'k2':'v2'}
return render(request, '3/var.html', {'lists':lists, 'dicts':dict}
# var.html
{{ lists }}
<table border=1>
<tr>
<td>{{ lists.0 }}</td>
</tr>
</table><br>
{{ dicts }}
<table border=1>
<tr>
<td>{{ dicts.k1 }}</td>
</tr>
</table>
#urls.py
urlpatterns=[path('vars/', views.var), ...]
2)模板标签
模板标签用于载入代码渲染模板,或对传递参数进行逻辑判断和计算。模板标签用标签限定符{% %}进行包裹。
| 模板标签 | 描述 |
|---|---|
| {% if %}{% endif %} | 条件判断 |
| {% for %}{% endfor %} | 循环 |
| {% uri %} | 路由配置的地址标签 |
| {% extends xx %} | 模板继承标签,继承于xx模板 |
| {% load %} | 加载相关内容 |
| {% static %} | 静态资源 |
| {% block %}{% endblock %} | 一组占位符标签,需要重写模板 |
| {% csrf_token %} | 用于防护跨站请求伪造攻击 |
| {% include 页面 %} | 包含一个html页面 |
3)模板过滤器
模板过滤器用于对模版变量进行操作。语法格式为{{ variable_name | filter: parameters }}。
| 模板过滤器 | 格式 | 描述 |
|---|---|---|
| data | {{ name|date:“Y-m-d G:i:s” }} | 格式化输出时间日期变量 |
| length | {{ name|length }} | 获取变量长度 |
| safe | {{ name|safe }} | 关闭html标签和js标签的自动转义功能 |
| slice | {{ name|slice:“2:4” }} | 切片语法 |
如果网站中的多个页面具有相同的部分,则可以将这部分抽取出来建立一个基础模版/母版页,从而实现代码复用、提高开发效率。
1)母版页示例
<html>
<head><\head>
{ % block title % }
<title>母版页title>
<body>
<table border="1" style="width: 700px;">
<tr>
<td colspan="2" style="height:30px;text-align:center;">TOP区td>
tr>
<tr style="vertical-align:middle; height:300px;">
<td style="width:200px;">
左边的菜单栏
td>
<td style="width:500px;">
{ % block content % }
内容可变区
{ % endblock % }
td>
tr>
<tr>
<td colspan="2" style="height:30px;text-align:center;">
版权区
td>
tr>
table>
body>
html>
2)内容页
{ % extends "base.html" % }
{ % block title % }
<title>欢迎页title>
{ % end block % }
{ % block content % }
<div styl"text-align: center;">栓Q歪瑞玛曲div>
{ % endblock % }
3)设计组件
base.html
<html>
<head>head>
{ % block title % }
<title>母版页标题title>
{ % endblock % }
<body>
<table border="1" style="width:700px;">
<tr>
<td colspan="2">{ % include 'top.html' % }
td>
tr>
<tr style="vertical-align:middle; height:300px;">
<td style="width:200px;">左边的菜单栏td>
<td style="width:500px;">
{ % block content % }
内容可变区
{ % endblock % }
td>
tr>
<tr>
<td colspan="2" style="height:30px;text-align:center;">
{ % include 'footer.html' % }
td>
table>
body>
html>
top.html
<table border="1" style="width:100%;">
<tr>
<td colspan="2" style="height:30px;text-align:center;">TOP区td>
tr>
除了上述的html文件,网页一般还有css文件和javascript文件。
静态文件包括static和media两类,前者包括css, js, Images等;后者指媒体文件,如用户上传的文件等。
在Django中,需要在根目录手动创建static和media文件夹来存放对应的文件。调试模式和生产模式的配置有所不同。
# Debug=True: setting.py
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
STATIC_URL = '/static/'
# Debug=False: 1/2 setting.py
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# Debug=False: 2/2 urls.py
urlpatterns=[
re_path('media/(?P.*)' , serve, {"document_root":settings.MEDIA_ROOT}),
re_path('static/(?P.*)' , serve, {"document_root": settings.STATIC_ROOT}),
]
Django通过模型/Model来实现与数据库的交互功能,如增、删、改、查、多表关联等。Django框架目前支持SQLite, MySQL, PostgrepSQL等数据库。