Django之URL分发器

URL映射:

视图写完后,要与URL进行映射(即用户在浏览器中输入什么样的url可以请求到这个视图函数),Django会从url.py文件中寻找相对应的视图,这个文件中有个urlpatterns变量,这个变量中通过path函数包含着要请求的视图。为什么会从url.py文件中寻找呢,因为在setting中有个ROOT_URLCONF = 'gjz.urls';所有的URL映射都是从这个项目的url文件中开始。

view.py文件:

from django.http import HttpResponse

def index(request):
    return HttpResponse("ok")

项目的url.py文件:

from django.contrib import admin
from django.urls import path,include
from front import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path("index/",views.index),
]

当我们在浏览器中输入127.0.0.1:8000/index的时候Django会从url.py文件中寻找path函数包含的匹配规则中的index/,并映射到对应的视图。

URL的模块化:一个Django项目是由多个app组成的,如果把每个APP的url映射都放到项目的url文件中显得太多了,不好管理,最好的办法就是把每个APP的映射条件放到自己的APP内,即在自己的APP内添加一个url文件,这个url文件中包含着自己app的映射关系,即url的模块化。

比如有两个APP一个Front,一个CMS模块那么该如何映射呢:

1APP中添加url.py文件

2项目的url.py文件中包含每个app的url.py文件,项目url.py代码如下:

from django.contrib import admin
from django.urls import path,include
urlpatterns = [
    path('admin/', admin.site.urls),
    path("front/",include("front.urls")),
    path("cms",include("cms.urls")),
]

3每个APP的url.py代码:

Front中的url.py

from django.urls import path
from . import views
urlpatterns=[
    path("",views.index),
]

cms的url.py

from django.urls import path
from . import views
app_name = "cms"
urlpatterns = [
    path("",views.index),
]

当我们在浏览器中输入127.0.0.1:8000/front的时候,Django会从项目的url文件中开始找,找到后再去include包含的url中接着找,然后在返回对应的视图。

path()函数与repath()函数:

path()函数与repath()函数最大的区别就是repath()第一个参数route可以使用正则表达式来实现一些复制的需求。

path()定义为:path(route,view,name=None,kwargs=None);前两个参数是必须的后面两个可以省略

  route参数:url的匹配规则。可以传递参数以<>尖括号的形式传递,并且可以指定参数的类型:

      <int:id>:匹配热议的零或者正整数

      <str:id>:非空的字符串类型

      <uuid>:匹配uuid字符串

      <path>:非空英文字符串,可以包含斜杠

  view参数:视图函数或者类视图函数或者include()函数的返回值

  name参数:这个URL的名字

  kwargs参数:可以给视图传递一些额外的参数,这个参数是一个字典类型

include()函数:

包含一个APP的url.py文件或者包含一个列表(元组),这个列表(元组)中是path函数(repath())

from django.contrib import admin
from django.urls import path,include
from cms import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path("front/",include("front.urls")),   #包含的是一个url文件
    path("cms",include([                   #包含的是一个path列表
        path("", views.index),
        path("book", views.login)
    ])),
]

URL中添加参数:

  1默认参数:直接在视图中添加一个参数

   

from django.http import HttpResponse
books=[
    "三国演义",
    "水浒传",
    "西游记",
    "红楼梦"
]
def index(request):
    return HttpResponse("ok")

def book(request,id=1):     #不带参数直接访问book则返回 “水浒传”
    return HttpResponse(books[id]) 

  2查询字符串参数:

def index(request):
    ID = request.GET.get("id")
    return HttpResponse(ID)

浏览器中输入:127.0.0.1:8000/front/?id=3;
则返回数字3
查询字符串通过request.GRT.get("字符串名字”)获取;浏览器通过?id=123(?字符串=值)

  3传递参数:

  (1)path()函数传递参数:path("book/<int:id>"),视图中必须接受这个参数:def index(request,id)

    (2)  repath()函数传递参数:repath(r"book/(<int:id>)");视图中必须接受这个参数:def index(request,id)

  (3)传递参数时,html中的设置:

  <ul><li><a href="{% url 'front:book_detail' book.id  %}">参数页</a></li>   //book_id 为参数;左右留空格</ul>

 

reverse()函数:在我们实际开发过程中url的名字可能会变动比如登入一开始用login后来变为signin,那么我们在其他地方可能会用到这个名字,这里一旦改变其他的地方也要改变很麻烦,这个时候就会用到name属性给这个url取个别名,然后再反转reverse()得到。

url.py

from django.urls import path
from . import views
urlpatterns=[
    path("index",views.index,name="index"),
    # path("book/<int:id>",views.book,name="book"),  #一开始url的名字是book,后来变为book_list了也不会妨碍重定向
    path("book_list/<int:id>",views.book,name="book"),  #name=book,给这url去个别名,可以通过这个别名来找到这个url
]

views.py

from django.http import HttpResponse
from django.shortcuts import redirect,reverse
books=[
    "三国演义",
    "水浒传",
    "西游记",
    "红楼梦"
]
def index(request):
    return redirect(reverse("book",kwargs={"id":3}))  #带关键字的反转

def book(request,id=1):
    return HttpResponse(books[id])

 

应用命名空间与实例命名空间:

  应用命名空间:是给这个app取个名字;作用:每个APP可能会有相同url的名字,比如前台和后台都有登入的界面login,那么当我们输入login是去前台的界面呢还是后台的界面呢?这个时候就需要指定app的名字了。

from django.urls import path
from . import views
app_name = "cms"   #给这个APP取个名字叫做cms
urlpatterns = [
    path("",views.index),
    path("login/",views.login),
    path("book<int:id>/",views.book),
]
from django.http import HttpResponse
from django.shortcuts import redirect,reverse
books=[
    "三国演义",
    "水浒传",
    "西游记",
    "红楼梦"
]
def index(request):
    return redirect(reverse("cms:book",kwargs={"id":3}))  #当我们要跳转到cms中的book界面的时候用cms:book方式

  实例命名空间:一个app可以创建多个实例,即多个url映射同一个app,这样在做反转的时候容易混乱。这个时候就需要实例命名空间了,只需要在include函数中传递一个namespace变量即可。

"""
from django.contrib import admin
from django.urls import path,include
from cms import views
urlpatterns = [
    path("front1/",include("front.urls",namespace="front1")),
    path("front2/",include("front.urls",namespace="front2"),),    #front1和front2同时映射到了front.urls模块,为了区分他们使用实例命名空间
]

views.py

from django.http import HttpResponse
from django.shortcuts import redirect,reverse
def index(request):
    current_app = request.resolver_match.namespace      #获取当前实例命名空间的名字
    return redirect(reverse("%s:book" %current_app,kwargs={"id":2}))   #使用这个url来找到book

def book(request,id):
    return HttpResponse("book")

自定义URL转换器:

 

posted @ 2018-12-28 00:47  漏斗倒过来  阅读(493)  评论(0编辑  收藏  举报