Url进阶

mysit/mysit/urls.py

  1. from django.conf.urls import url
  2. from django.contrib import admin
  3.  
  4. urlpatterns = [
  5. url(r'^admin/', admin.site.urls),
  6. ]
  7.  
  8. # urlpatterns=[
  9. # url(正则表达式,视图函数,参数,别名)
  10. # ]
  11. #
  12. # 正则表达式:python正则表达式的所有规则都适应,当用户输入满足正则表达式的地址时就会执行对应的视图函数
  13. # 视图函数:urls本质是一个映射表,每个url地址都对应一个视图函数,第一个参数是地址,第二个参数就是处理这个地址的视图函数
  14. # 参数:视图函数有时需要参数,就需要第三个参数来给视图函数传递参数,是字典形式的参数
  15. # 别名:这个是用在前端的,一会儿会介绍
  16. #
  17. # 当我们每次新建一个URL和其对应的视图函数时都会在views.py中的urlpatterns列表里添加“url(正则表达式,视图函数,参数,别名)”

小实例1

mysit/mysit/urls.py修改如下

  1. from django.conf.urls import url
  2. from django.contrib import admin
  3. from blog import views
    # 导入blog下的views.py
  4.  
  5. urlpatterns = [
  6. url(r'^admin/', admin.site.urls),
  7. url(r'^years/[0-9]{4}',views.years)
  8. # 满足正则表达式则'^years/[0-9]{4}' 则运行views.years视图函数
  9. ]

mysit/blog/views.py修改如下

  1. from django.shortcuts import render, HttpResponse
  2.  
  3. # Create your views here.
  4.  
  5. def years(requst):
  6. return HttpResponse("this is my webpage")

运行,输入网址显示效果:


小实例2

继续修改

mysit/blog/views.py修改如下

  1. from django.shortcuts import render, HttpResponse
  2.  
  3. # Create your views here.
  4.  
  5. def years(requst, var_one,var_year):
  6. # 这次我们视图函数需要一个参数var_year,并将该参数返回给页面
  7. return HttpResponse(str(var_one)+str(var_year))

mysit/mysit/urls.py修改如下

  1. from django.conf.urls import url
  2. from django.contrib import admin
  3. from blog import views
  4.  
  5. urlpatterns = [
  6. url(r'^admin/', admin.site.urls),
  7.  
  8. url(r'^years/[0-9]{4}', views.years, {"var_year": 2008, "var_one": "years"})
  9. # 满足正则表达式则'^years/[0-9]{4}' 则运行views.years视图函数,
  10. # 由于视图函数views.years需要参数,所以我们的url()也要添加第三个参数
  11. # 第三个参数将视图函数所需的参数封装成字典,key为views.years中的参数名称,value是想要给他的值
  12.  
  13. # 另一种传递参数方法
  14. # url(r'^(years)/([0-9]{4})',views.years)
  15. # 正则表达式中只要用()包含起来的内容都会当作参数传递给views.years
  16. # 只能按照括号的顺序挨个给视图函数中的参数
  17.  
  18. # 另一种传递参数方法
    # url(r'^(?P<var_one>years)/(?P<var_year>[0-9]{4})',views.years)
    # 正则表达式中用()包含起来的内容有了名字 ?P<name> 传递给视图函数的时候会找到相对应的参数
    # 可以不按照顺序
  1. ]

运行,输入网址显示效果:


小实例3

mysit/templates下新建myhtml.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. {#form表单提交的数据内容都会交给action中的index (127.0.0.1:8000/index,省略了IP和端口)去处理#}
  9. <form action="/index/" method="post" >
  10. <input type="text">
  11. <input type="submit" value="提交">
  12. </form>
  13.  
  14. </body>
  15. </html>

mysit/mysit/urls.py修改如下

  1. from django.conf.urls import url
  2. from django.contrib import admin
  3. from blog import views
  4.  
  5. urlpatterns = [
  6. url(r'^admin/', admin.site.urls),
  7. url(r'^index', views.years)
  8. ]

mysit/blog/views.py修改如下

  1. from django.shortcuts import render, HttpResponse
  2.  
  3. # Create your views here.
  4.  
  5. def years(requst):
  6. if requst.method == "POST":
  7. # 提交表单的时候是POST请求,返回提交成功
  8. return HttpResponse("提交成功!")
  9.  
  10. # 第一次访问为GET请求 直接返回带有表单的页面
  11. return render(requst, "myhtml.html")

运行,结果正常,可是如果有个需求,需要你改变一下网址,不是输入http://127.0.0.1:8000/index/会访问该页面,而是输入http://127.0.0.1:8000/index/pay访问该页面,那么你需要修改两个地方:

1. 将mysit/mysit/urls.py 中的“url(r'^index', views.years)”修改为“url(r'^index/pay', views.years)”,

2,将mysit/templates/myhtml.html中的“<form action="/index/" method="post" >”修改为“<form action="/index/pay/" method="post" >”,

可能并不感觉麻烦,但是我的需求不想让前端修改HTML代码,怎么办?这就引入了 url(正则表达式,视图函数,参数,别名)中的“别名”

小实例4

mysit/blog/views.py不用修改

mysit/templates/myhtml.html修改如下

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. {#form表单提交的数据内容都会交给urls.py中别名为“pay”对应的视图函数去处理#}
  9. {#固定写法action={% url " " %} 引号中为别名,与后端urls.py中的别名一致#}
  10. <form action={% url "pay" %} method="post" >
  11. <input type="text">
  12. <input type="submit" value="提交">
  13. </form>
  14.  
  15. </body>
  16. </html>

mysit/mysit/urls.py修改如下

  1. from django.conf.urls import url
  2. from django.contrib import admin
  3. from blog import views
  4.  
  5. urlpatterns = [
  6. url(r'^admin/', admin.site.urls),
  7. url(r'^index/$', views.years, name="pay")
  8. # 固定写法 name="" 引号中为别名
  9. # 别名的作用就是当需要修改正则表达式,即当你需要换网址的时候不用修改前端的HTML页面
  10. # 前提是你的name值与前端的{% url " " %}引号中的值一样
  11. ]

这样,无论你想修改什么样的正则表达式,即想修改什么样的网址,前端都不用动,提交表单时,都会去找别名为“pay”所对应的视图函数。


小实例5

肯定有人问,如果一个网站有成千上万个url地址,那么都放到mysit/mysit/urls.py里吗?既不容易修改,也不利于查找,怎么办?

mysit/mysit/urls.py修改如下

  1. from django.conf.urls import url,include
  2. # 导入include模块
  3. from django.contrib import admin
  4.  
  5. urlpatterns = [
  6. url(r'^admin/', admin.site.urls),
  7. url(r'^blog/',include("blog.urls"))
  8. # 固定语法 以后所有以blog开头的地址,都会去blog/urls.py中去查找分发
  9. # url(正则表达式,include("对应的app urls"))
  10. ]

mysit/blog/下新建urls.py

  1. from django.conf.urls import url
  2. from blog import views
  3.  
  4. urlpatterns = [
  5. url(r'index/', views.years, name="pay"),
  6. url(r'index2/', views.years, name="pay2"),
  7. url(r'index3/', views.years, name="pay3")
  8.  
  9. ]

这样问题就解决了,mysit/mysit/urls.py其实是总的URL分发,满足条件则去 mysit/blog/urls.py实现具体分发

View进阶

可能你会有疑惑,为什么每次在views.py中写视图函数的时候,每个函数必须有个参数request,现在我们来一探究竟:

HttpRequest对象

  1. from django.shortcuts import render
  2.  
  3. # Create your views here.
  4.  
  5. def years(request):
  6. # request其实是一个HttpRequest对象,他包含了用户传递过来的所有信息,主要属性及方法如下:
  7.  
  8. print("request.path:" + str(request.path))
  9. # 执行结果:request.path:/blog/index/
  10. # 请求页面的全路径,不包括域名
  11.  
  12. print("request.method:" + str(request.method))
  13. # 执行结果:request.method:GET
  14. # 请求中使用的HTTP方法的字符串表示。全大写表示
  15. # GET: 包含所有HTTP GET参数的类字典对象
  16. #
  17. # POST: 包含所有HTTP POST参数的类字典对象
  18. #
  19. # 服务器收到空的POST请求的情况也是可能发生的,也就是说,表单form通过
  20. # HTTP POST方法提交请求,但是表单中可能没有数据,因此不能使用
  21. # if req.POST来判断是否使用了HTTP POST 方法;应该使用 if req.method=="POST"
  22.  
  23. print("request.COOKIES:" + str(request.COOKIES))
  24. # 执行结果:request.COOKIES:{}
  25. # 包含所有cookies的标准Python字典对象;keys和values都是字符串。
  26.  
  27. print("request.session:" + str(request.session))
  28. # 执行结果:request.session:<django.contrib.sessions.backends.db.SessionStore object at 0x7fa23a3e37f0>
  29. # session: 唯一可读写的属性,代表当前会话的字典对象;自己有激活Django中的session支持时该属性才可用。
  30.  
  31. print("request.user:" + str(request.user))
  32. # 执行结果: request.user:AnonymousUser
  33. # user: 是一个django.contrib.auth.models.User对象,代表当前登陆的用户。如果访问用户当前
  34. # 没有登陆,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。你
  35. # 可以通过user的is_authenticated()方法来辨别用户是否登陆:
  36. # if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware
  37. # 时该属性才可用
  38.  
  39. print("request.FILES:" + str(request.FILES))
  40. # 执行结果:request.FILES:<MultiValueDict: {}>
  41. # FILES: 包含所有上传文件的类字典对象;FILES中的每一个Key都是<input type="file" name="" />标签中
  42. # name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包含下面三个Keys:
  43. #
  44. # filename: 上传文件名,用字符串表示
  45. # content_type: 上传文件的Content Type
  46. # content: 上传文件的原始内容
  47. # 方法
  48. # get_full_path(), 比如:http://127.0.0.1:8000/index33/?name=123,
  49. # req.get_full_path()
  50. # 得到的结果就是 /index33/?name =123 包括用户GET过来的数据
  51. # 而req.path: 则得到 /index33 不包括用户GET过来的数据
  52. return render(request, "myhtml.html")

HttpResponse对象

每个view请求处理方法必须返回一个HttpResponse对象。所以每个views.py下的函数都会return一个HttpResponse对象,其实render、HttpResponse以及还每接触到的redirect都是HttpResponse对象,HttpResponse只是返回一堆HTML字符串他不会渲染网页,假如你的网页中存在变量,则需要render,假如页面跳转,那么就需要redirect,下面实例告诉你redirect和render的区别。

我们实现一个功能:浏览器输入网址http://127.0.0.1:8000/blog/index/将myhtml.html页面返回给用户让用户登录,用户点击提交后将myhtml2.html页面返回给用户,下面我们先用render进行实现:

mysit/templates/新建myhtml.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. {#form表单提交的数据内容都会交给urls.py中别名为“pay”对应的视图函数去处理#}
  9. <form action={% url "pay" %} method="post" >
  10. <input type="text">
  11. <input type="submit" value="提交">
  12. </form>
  13.  
  14. </body>
  15. </html>

mysit/templates/新建myhtml2.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. {# 视图函数返回来的username进行显示 #}
  9. 欢迎{{ username }}登录
  10. </body>
  11. </html>

mysit/mysit/urls.py进行路径分发,满足条件'^blog/'则去 mysit/blog/urls.py实现具体分发

  1. from django.conf.urls import url,include
  2. # 导入include模块
  3. from django.contrib import admin
  4.  
  5. urlpatterns = [
  6. url(r'^admin/', admin.site.urls),
  7. url(r'^blog/',include("blog.urls"))
  8. # 所有以“blog/”开头的url地址都分配给"blog.urls"再进行分发
  9. ]

mysit/blog/urls.py

  1. from django.conf.urls import url
  2. from blog import views
  3.  
  4. urlpatterns = [
  5. url(r'index/$', views.myhtml, name="pay"),
  6.   # 分别分配视图函数
  7. url(r'index2/$', views.myhtml2),
  8.  
  9. ]

mysit/blog/views.py

  1. from django.shortcuts import render, HttpResponse, redirect
  2.  
  3. # 首先导入 HttpResponse, redirect
  4.  
  5. # Create your views here.
  6.  
  7. def myhtml(request):
  8. if request.method == "POST":
  9. # 做一些判断 判断成功后将 登录后的页面"myhtml2.html" 返回给用户
  10. return render(request, "myhtml2.html")
  11.  
  12. return render(request, "myhtml.html")
  13.  
  14. def myhtml2(request):
  15. username = "IDKTP"
  16. # 一些操作 比如从数据库拿到该用户的某些信息 然后返回页面给用户
  17. # 我们只返回给用户自己的姓名进行显示 让页面显示 欢迎IDKTP登录
  18. return render(request, "myhtml2.html", {"username": username})

点击运行,浏览器输入网址http://127.0.0.1:8000/blog/index/,再在页面中点击“提交”按钮,你会发现:

那是因为render直接在当前url网址(127.0.0.1:8000/blog/index)中把myhtml2.html页面返回给了用户,而在def myhtml2(request)视图函数中的所有操作(给username进行赋值)都没有进行,所以myhtml2.html中的“{{ username }}”为空,所以没有显示。

而redirect则会直接改变地址栏中url地址,然后根据url分发找到def myhtml2(request)视图函数,然后在返回myhtml2.html页面

mysit/blog/views.py修改如下

  1. from django.shortcuts import render, HttpResponse, redirect
  2.  
  3. # 首先导入 HttpResponse, redirect
  4.  
  5. # Create your views here.
  6.  
  7. def myhtml(request):
  8. if request.method == "POST":
  9. # 做一些判断 判断成功后将 登录后的页面"myhtml2.html" 返回给用户
  10. return redirect("/blog/index2")
  11. # redirect("")引号内为页面myhtml2.html对应的url地址
  12.  
  13. # "/blog/index2"开头以“/”开头 证明url地址是"/blog/index2"直接和 域名 进行拼接
  14. # (127.0.0.1:8000/blog/index2)
  15.  
  16. # "blog/index2"不是以“/”开头 证明url地址是 你跳转之前的url地址 和 "blog/index2"进行拼接
  17. # (127.0.0.1:8000/blog/index/blog/index2)
  18.  
  19. return render(request, "myhtml.html")
  20.  
  21. def myhtml2(request):
  22. username = "IDKTP"
  23. # 一些操作 比如从数据库拿到该用户的某些信息 然后返回页面给用户
  24. # 我们只返回给用户自己的姓名
  25. return render(request, "myhtml2.html", {"username": username})

这样就实现了我们想要的结果了!

Django进阶(一)的更多相关文章

  1. Python之路,Day16 - Django 进阶

    Python之路,Day16 - Django 进阶   本节内容 自定义template tags 中间件 CRSF 权限管理 分页 Django分页 https://docs.djangoproj ...

  2. django进阶补充

    前言: 这篇博客对上篇博客django进阶作下补充. 一.效果图 前端界面较简单(丑),有两个功能: 从数据库中取出书名 eg: 新书A 在form表单输入书名,选择出版社,选择作者(多选),输入完毕 ...

  3. django进阶-3

    先看效果图: 登陆admin后的界面: 查看作者: 当然你也可以定制admin, 使界面更牛逼 数据库表结构: app01/models.py from django.db import models ...

  4. django进阶-4

    前言: 下篇博客写关于bootstrap... 一.如何在脚本测试django from django.db import models class Blog(models.Model): name ...

  5. Django进阶篇【1】

    注:本篇是Django进阶篇章,适合人群:有Django基础,关于Django基础篇,将在下一章节中补充! 首先我们一起了解下Django整个请求生命周期: Django 请求流程,生命周期: 路由部 ...

  6. Django进阶知识

    drf学习之Django进阶点 一.Django migrations原理 1.makemigrattions: 相当于在每个app下的migrations文件夹下生成一个py脚本文件用于创建表或则修 ...

  7. django进阶-查询(适合GET4以上人群阅读)

    前言: 下篇博客写关于bootstrap... 一.如何在脚本测试django from django.db import models class Blog(models.Model): name ...

  8. django进阶-modelform&admin action

    先看效果图: 登陆admin后的界面: 查看作者: 当然你也可以定制admin, 使界面更牛逼 数据库表结构: app01/models.py from django.db import models ...

  9. django进阶-小实例

    前言: 这篇博客对上篇博客django进阶作下补充. 一.效果图 前端界面较简单(丑),有两个功能: 从数据库中取出书名 eg: 新书A 在form表单输入书名,选择出版社,选择作者(多选),输入完毕 ...

  10. django进阶-1

    前言: 各位久等了,django进阶篇来了. 一.get与post 接口规范: url不能写动词,只能写名词 django默认只支持两种方式: get, post get是获取数据 ?user=zcl ...

随机推荐

  1. 数据结构:堆排序 (python版) 小顶堆实现从大到小排序 | 大顶堆实现从小到大排序

    #!/usr/bin/env python # -*- coding:utf-8 -*- ''' Author: Minion-Xu 小堆序实现从大到小排序,大堆序实现从小到大排序 重点的地方:小堆序 ...

  2. 计算(LnN!)的值

    import java.util.*;import java.math.*;public class CaculatorLnN { public static void main(String[] a ...

  3. 【夯实PHP基础】PHP的反射机制

    本文地址 分享提纲: 1. 介绍 2. 具体例子 2.1 创建Persion类 2.2 反射过程 2.3 反射后使用 1. 介绍 -- PHP5添加了一项新的功能:Reflection.这个功能使得p ...

  4. Xcode7使用插件的简单方法&&以及怎样下载到更早版本的Xcode

    Xcode7自2015年9上架以来也有段时间了, 使用Xcode7以及Xcode7.1\Xcode7.2的小伙伴会发现像VVDocumenter-Xcode\KSImageNamed-Xcode\HO ...

  5. ReactiveCocoa 冷热订阅(cold subscribe, hot subscribe)

    ReactiveCocoa支持两种订阅方式,一种是冷订阅,一种是热订阅. 热订阅的特点: 1.不管有没有消息订阅着,发送者总会把消息发出去. 2.不管订阅者是什么时候订阅的,发送者总是会把相同的消息发 ...

  6. IOS 网络-深入浅出(一 )-> 三方SDWebImage

    首要我们以最为常用的UIImageView为例介绍实现原理: 1)UIImageView+WebCache:  setImageWithURL:placeholderImage:options: 先显 ...

  7. A星寻路算法介绍

    你是否在做一款游戏的时候想创造一些怪兽或者游戏主角,让它们移动到特定的位置,避开墙壁和障碍物呢? 如果是的话,请看这篇教程,我们会展示如何使用A星寻路算法来实现它! 在网上已经有很多篇关于A星寻路算法 ...

  8. 在 CentOS7 上安装 zookeeper-3.4.9 服务

    在 CentOS7 上安装 zookeeper-3.4.9 服务 1.创建 /usr/local/services/zookeeper 文件夹: mkdir -p /usr/local/service ...

  9. 了解npm的文件结构(npm-folders)和配置文件(npm-mrc)

    一.npm的文件结构 npm的安装: 本地安装 1. 将安装包放在 ./node_modules 下(运行 npm 命令时所在的目录),如果没有 node_modules 目录,会在当前执行 npm ...

  10. JavaScript & PHP模仿C#中string.format效果

    1.JavaScript function stringformat() { var args = Array.prototype.slice.call(arguments); if (args.le ...