• day053Django基础之url控制器、视图函数、模板


    本节内容: 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文件
    {# 这里可以动态的获得path路径 #} {% csrf_token %} 用户名 密码
    命名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 且提交的
    带有enctype="multipart/form-data" 的情况下才会 包含数据。否则,FILES 将为一个空的类似于字典的对象。 9.HttpRequest.COOKIES   一个标准的Python 字典,包含所有的cookie。键和值都为字符串。 10.HttpRequest.session   一个既可读又可写的类似于字典的对象,表示当前的会话。只有当Django 启用会话的支持时才可用。 完整的细节参见会话的文档。 11.HttpRequest.user(用户认证组件下使用)   一个 AUTH_USER_MODEL 类型的对象,表示当前登录的用户。   如果用户当前没有登录,user 将设置为 django.contrib.auth.models.AnonymousUser 的一个实例。你可以通过 is_authenticated() 区分它们。 例如: if request.user.is_authenticated(): # Do something for logged-in users. else: # Do something for anonymous users.   user 只有当Django 启用 AuthenticationMiddleware 中间件时才可用。 ------------------------------------------------------------------------------------- 匿名用户 class models.AnonymousUser django.contrib.auth.models.AnonymousUser 类实现了django.contrib.auth.models.User 接口,但具有下面几个不同点: id 永远为None。 username 永远为空字符串。 get_username() 永远返回空字符串。 is_staff 和 is_superuser 永远为False。 is_active 永远为 False。 groups 和 user_permissions 永远为空。 is_anonymous() 返回True 而不是False。 is_authenticated() 返回False 而不是True。 set_password()、check_password()、save() 和delete() 引发 NotImplementedError。 New in Django 1.8: 新增 AnonymousUser.get_username() 以更好地模拟 django.contrib.auth.models.User。 PythonCopy 2、request常用方法 1.HttpRequest.get_full_path()   返回 path,如果可以将加上查询字符串。   例如:"/music/bands/the_beatles/?print=true" 2.HttpRequest.is_ajax()   如果请求是通过XMLHttpRequest 发起的,则返回True,方法是检查 HTTP_X_REQUESTED_WITH 相应的首部是否是字符串'XMLHttpRequest'。   大部分现代的 JavaScript 库都会发送这个头部。如果你编写自己的 XMLHttpRequest 调用(在浏览器端),你必须手工设置这个值来让 is_ajax() 可以工作。   如果一个响应需要根据请求是否是通过AJAX 发起的,并且你正在使用某种形式的缓存例如Django 的 cache middleware, 你应该使用 vary_on_headers('HTTP_X_REQUESTED_WITH') 装饰你的视图以让响应能够正确地缓存。 PythonCopy 3、HttpResponse对象 响应对象主要有三种形式(响应三剑客): HttpResponse() render() redirect() HttpResponse()括号内直接跟一个具体的字符串作为响应体, 比较直接很简单,return HttpResponse("Error!") 所以这里主要介绍后面两种形式。 4、render()重点 render方法KEY: 1 找文件,读文件 2 渲染数据 3 把最终渲染的字符串交给HttpResponse返回 写法: render(request, template_name, [context]) 结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。 views.py文件 def index(request): good_list=['小米电视',"海尔冰箱","格力空调","AAA"] # 这里暂时模拟数据库 return render(request,"index.html",{"good_list":good_list}) # 必须传前面两个参数,后面一个可以不传,这样html里{{}}就为空,浏览器永远看不到两个大括号的, # 第三个参数,是字典的键值对,键为HTML的{{ }}里的字符串,值为我们读取数据库的数据 # render(三个参数的)执行过程解析: 1、首先去templates里找HTML文件,找到了不是马上返回HTML字符串,先识别有没有{{ }}或者{% %} 2、找到了{{ }},将第三个参数的数据替换{{ }}(类似于写入清空{{ }}),完成了渲染 3、将渲染后的html文件返回给浏览器 最终也是返回字符串,只不过他返回的是一个页面字符串 index.html文件

    This is Index!


    商品列表

    {{ good_list }} // 这里是render会识别去渲染他,{{ good_list}}是整个被替换 PythonCopy 5、redirect()重点 作用:重定向,(在原地址基础上直接指定跳转一个链接地址) 业务场景:登录成功后,直接在登录页面跳转自己的个人首页 各个文件代码示例 # 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 index(request): good_list=['小米电视',"海尔冰箱","格力空调","AAA"] # 模拟去数据库取的数据 return render(request,"index.html",{"good_list":good_list}) def login(request): if request.method=="GET": # 通过请求方式,判断获取登录页面,还是登录验证请求 return render(request,"login.html") else: #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!") # redict执行流程解析 1、执行到这里,登录验证肯定是成功的,这里就要给用户跳转到个人首页 # 这里redirect会发送两次响应给浏览器, 2、首先,redirect发一个没有响应体的响应给浏览器,但是响应状态码为301, 浏览器一读取到这个状态码,就知道要立刻再发送一个请求给服务器, 才能拿到真正的响应体,这一步的操作,是浏览器做的,用户并不知道的 (请求的路径在响应头里的location,) 3、浏览器把真正的求路径发过来,服务器接收到后,经过urls路由分发, 执行该路径的视图函数后,把相应的html页面的字符串返回给浏览器, # redirct的优点: 1、return redirect("/index/"),这里他自己会去调用index视图函数,实现了代码复用 2、在我们登录成功后,如果卡了,那么刷新,就不会再跑到还要登录输入的页面, 因为此时的路径已经是你个人页面的路径了,实现了重定向 PythonCopy # login.py文件 用户名 密码 PythonCopy # index.py文件

    This is Index!


    商品列表

    {{ good_list }} PythonCopy 四、MTV之模板 1、渲染变量: {{}} 深度查询 句点符,一直点就是一直往里查找 过滤器 {{ val|filter_name:参数 }} 2、渲染标签: {%%} {%for%} {%endfor%} 1、模板语法之变量(深度查询) 在 Django 模板中遍历复杂数据结构的关键是句点字符, 变量渲染过程: 1、views.py里的视图函数,拿到要传递给template文件的值(数据), 2、将变量通过render方法第三个参数以{"": }形式传入给template模板文件; 3、template里面用{{ "变量名" }},(变量名作为上面参数的键,一般我们键名=值名写一样的) 4、这样render方法在加载template文件时就会识别{{ }},从而对变量进行渲染 5、渲染完成后再将整个template文件以字符串发送给浏览器。 view.py文件代码示例 def index(request): s="alex" # 字符串 l=[111,222,333,444] # 列表 info={"name":"alex","age":34,"addr":"沙河"} # 字符串 class Animal(object): # 自定义类对象 def __init__(self,name,age): self.name=name self.age=age def paojiao(self): return 666 alex=Animal('alex',"45") egon=Animal('egon',"25") person_list=[alex,egon] return render(request,"index.html",{"s":s,"l":l,"info":info,"perso_list",person_list}) PythonCopy template的index.html文件变量示例

    模板语法之变量

    {{ name }}

    深度查询:句点符 .

    {{ l }}

    {{ l.0 }}

    # 深度查询

    {{ info }}

    {{ info.name }}

    {{ info.age }}

    {{ person_list }}

    {{ person_list.1.name }}

    # 可以一直往里查询,这就是深度

    {{ person_list.1.paojiao }}

    # 深度查询,只能调用无参的方法 # 示例:注意:句点符也可以用来引用对象的方法(无参数方法):

    字典:{{ dic.name.upper }}

    # 说白了就是括号也不能写 HTMLCopy 2、模板之过滤器—-Django自带的(格式化输出数据) 语法: {{obj|filter__name:param} 作用:就是格式化输出 解释:就是能穿过过滤器的,都按一样的格式输出 1、一些自带的过滤器 一些自带的过滤器作用详解 1、default 如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。例如: {{ value|default:"nothing" }} 2、length 返回值的长度。它对字符串和列表都起作用。例如: {{ value|length }} 如果 value 是 ['a', 'b', 'c', 'd'],那么输出是 4。 3、filesizeformat 将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。例如: {{ value|filesizeformat }} 如果 value 是 123456789,输出将会是 117.7 MB。   4、date 如果 value=datetime.datetime.now() {{ value|date:"Y-m-d" }}    5、slice 如果 value="hello world" {{ value|slice:"2:-1" }} 6、truncatechars 如果字符串字符多于指定的字符数量,那么会被截断。 截断的字符串将以可翻译的省略号序列(“...”)结尾。 参数:要截断的字符数 例如: {{ value|truncatechars:9 }} 8、truncatewords 截断多少个词

    {{ shi|truncatewords:5 }}

    # 要截断的多少个词, 7、safe Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。 但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统, 后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本, 如果自动转义的话显示的就是保护HTML标签的源文件。 为了在Django中关闭HTML的自动转义有两种方式, 如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。比如: value="点击" {{ value|safe}} HTMLCopy 3、模板之标签
  • 相关阅读:
    产品经理之路(八)
    产品经理之路(七)
    产品经理之路(六)
    产品经理之路(五)
    产品经理之路(四)
    产品经理之路(三)
    产品经理之路(二)
    react-admin-plus 正式开源, 欢迎star
    uni-app—从安装到卸载
    vue项目使用websocket技术
  • 原文地址:https://www.cnblogs.com/yipianshuying/p/10223401.html
Copyright © 2020-2023  润新知