Url进阶

mysit/mysit/urls.py

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

小实例1

mysit/mysit/urls.py修改如下

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

mysit/blog/views.py修改如下

from django.shortcuts import render, HttpResponse

# Create your views here.

def years(requst):
return HttpResponse("this is my webpage")

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


小实例2

继续修改

mysit/blog/views.py修改如下

from django.shortcuts import render, HttpResponse

# Create your views here.

def years(requst, var_one,var_year):
# 这次我们视图函数需要一个参数var_year,并将该参数返回给页面
return HttpResponse(str(var_one)+str(var_year))

mysit/mysit/urls.py修改如下

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

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


小实例3

mysit/templates下新建myhtml.html

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

mysit/mysit/urls.py修改如下

from django.conf.urls import url
from django.contrib import admin
from blog import views urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index', views.years)
]

mysit/blog/views.py修改如下

from django.shortcuts import render, HttpResponse

# Create your views here.

def years(requst):
if requst.method == "POST":
# 提交表单的时候是POST请求,返回提交成功
return HttpResponse("提交成功!") # 第一次访问为GET请求 直接返回带有表单的页面
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修改如下

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

mysit/mysit/urls.py修改如下

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

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


小实例5

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

mysit/mysit/urls.py修改如下

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

mysit/blog/下新建urls.py

from django.conf.urls import url
from blog import views urlpatterns = [
url(r'index/', views.years, name="pay"),
url(r'index2/', views.years, name="pay2"),
url(r'index3/', views.years, name="pay3") ]

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

View进阶

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

HttpRequest对象

from django.shortcuts import render

# Create your views here.

def years(request):
# request其实是一个HttpRequest对象,他包含了用户传递过来的所有信息,主要属性及方法如下: print("request.path:" + str(request.path))
# 执行结果:request.path:/blog/index/
# 请求页面的全路径,不包括域名 print("request.method:" + str(request.method))
# 执行结果:request.method:GET
# 请求中使用的HTTP方法的字符串表示。全大写表示
# GET: 包含所有HTTP GET参数的类字典对象
#
# POST: 包含所有HTTP POST参数的类字典对象
#
# 服务器收到空的POST请求的情况也是可能发生的,也就是说,表单form通过
# HTTP POST方法提交请求,但是表单中可能没有数据,因此不能使用
# if req.POST来判断是否使用了HTTP POST 方法;应该使用 if req.method=="POST" print("request.COOKIES:" + str(request.COOKIES))
# 执行结果:request.COOKIES:{}
# 包含所有cookies的标准Python字典对象;keys和values都是字符串。 print("request.session:" + str(request.session))
# 执行结果:request.session:<django.contrib.sessions.backends.db.SessionStore object at 0x7fa23a3e37f0>
# session: 唯一可读写的属性,代表当前会话的字典对象;自己有激活Django中的session支持时该属性才可用。 print("request.user:" + str(request.user))
# 执行结果: request.user:AnonymousUser
# user: 是一个django.contrib.auth.models.User对象,代表当前登陆的用户。如果访问用户当前
# 没有登陆,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。你
# 可以通过user的is_authenticated()方法来辨别用户是否登陆:
# if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware
# 时该属性才可用 print("request.FILES:" + str(request.FILES))
# 执行结果:request.FILES:<MultiValueDict: {}>
# FILES: 包含所有上传文件的类字典对象;FILES中的每一个Key都是<input type="file" name="" />标签中
# name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包含下面三个Keys:
#
# filename: 上传文件名,用字符串表示
# content_type: 上传文件的Content Type
# content: 上传文件的原始内容
# 方法
# get_full_path(), 比如:http://127.0.0.1:8000/index33/?name=123,
# req.get_full_path()
# 得到的结果就是 /index33/?name =123 包括用户GET过来的数据
# 而req.path: 则得到 /index33 不包括用户GET过来的数据
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

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

mysit/templates/新建myhtml2.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{# 视图函数返回来的username进行显示 #}
欢迎{{ username }}登录
</body>
</html>

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

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

mysit/blog/urls.py

from django.conf.urls import url
from blog import views urlpatterns = [
url(r'index/$', views.myhtml, name="pay"),
  # 分别分配视图函数
url(r'index2/$', views.myhtml2), ]

mysit/blog/views.py

from django.shortcuts import render, HttpResponse, redirect

# 首先导入 HttpResponse, redirect

# Create your views here.

def myhtml(request):
if request.method == "POST":
# 做一些判断 判断成功后将 登录后的页面"myhtml2.html" 返回给用户
return render(request, "myhtml2.html") return render(request, "myhtml.html") def myhtml2(request):
username = "IDKTP"
# 一些操作 比如从数据库拿到该用户的某些信息 然后返回页面给用户
# 我们只返回给用户自己的姓名进行显示 让页面显示 欢迎IDKTP登录
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修改如下

from django.shortcuts import render, HttpResponse, redirect

# 首先导入 HttpResponse, redirect

# Create your views here.

def myhtml(request):
if request.method == "POST":
# 做一些判断 判断成功后将 登录后的页面"myhtml2.html" 返回给用户
return redirect("/blog/index2")
# redirect("")引号内为页面myhtml2.html对应的url地址 # "/blog/index2"开头以“/”开头 证明url地址是"/blog/index2"直接和 域名 进行拼接
# (127.0.0.1:8000/blog/index2) # "blog/index2"不是以“/”开头 证明url地址是 你跳转之前的url地址 和 "blog/index2"进行拼接
# (127.0.0.1:8000/blog/index/blog/index2) return render(request, "myhtml.html") def myhtml2(request):
username = "IDKTP"
# 一些操作 比如从数据库拿到该用户的某些信息 然后返回页面给用户
# 我们只返回给用户自己的姓名
return render(request, "myhtml2.html", {"username": username})

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

最新文章

  1. Sharp Memory LCD (ls013b7dh03)驱动
  2. Android开源图表之树状图和饼状图的官方示例的整理
  3. Oracle数据访问组件ODAC的安装方法
  4. JavaBean学习总结(上)
  5. 分析Masonry
  6. DataGridView中添加CheckBox列用于选择行
  7. ionic button笔记
  8. IOS UITextField 设置光标位置
  9. 所有MVP文章
  10. iOS 容器控制器 (Container View Controller)
  11. Kubernetes使用cephfs作为后端存储
  12. 商务电话思维图(XMind f&#252;r Gesch&#228;ftliche Telefongespr&#228;che)
  13. Python2中文处理纪要
  14. Solve Error: &#39;NSInvalidArgumentException&#39;, reason: &#39;-[UITableView mas_makeConstraints:]: unrecognized selector sent to instance 0x7fa5c402fa00&#39;
  15. VBS数组导入Excel
  16. 学习net core的一些疑问?
  17. 微软Power BI 每月功能更新系列——10月Power BI 新功能学习
  18. 以太坊预言机与WEB API(原创,转载请说明原址)
  19. mysql快速移植表数据
  20. 软件project(一)——宏观总结

热门文章

  1. 【转译】加入ZigBee联盟,共画物联网的未来
  2. CSS3和javascript中的transform
  3. JS高程5.引用类型(3)Array类型-检测数组
  4. 负载均衡之LVS集群
  5. 使用IdleTest进行TDD单元测试驱动开发演练(1)
  6. Android Stuido 常用快捷键
  7. iOS快速集成友盟社会化分享功能(v6.1.1)
  8. Android XML中引用自定义内部类view的四个why
  9. UITableView cell复用出错问题 页面滑动卡顿问题 &amp; 各杂七杂八问题
  10. Java 中的集合接口——List、Set、Map