Django基础(3)_路由层

 路由层 (URLconf)

 路由层简单配置 

URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段逻辑代码对应执行。

 

 

path方法

写固定的url  

 

 注意后面必须有 / ,

 

re_path方法 

可以使用正则规则

1 urlpatterns = [
2     path('admin/', admin.site.urls),
3     path('articles/2003/', views.special_case_2003),
4     re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
5     re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
6     re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]+)/$', views.article_detail),
7 ]

 

Django2 用path Django1用url

 

1 from django.cong.urls import url

 

 path和url的区别

    path内部封装好了, 自动限制首尾的规则

    url 没有封装, 需要自己手动添加正则规则 (同re_path方法)

注意:

  • 若要从URL 中捕获一个值,只需要在它周围放置一对圆括号。
  • 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles而不是 ^/articles
  • 每个正则表达式前面的r是可选的但是建议加上。它告诉Python 这个字符串是“原始的” —— 字符串中任何字符都不应该转义

无名分组(按位置传参)

用re_path方法, 在url里用小括号进行分组(括号里面写上正则的规则)

re_path(r'^login/([0-9{4}])/([0-9]{2})$', views.login)
re_path(r'^books/(\d+)$',views.books)
re_path(r'^login/')

 注意: 在对应的视图函数中要写上对应的形参,否则会报错: 

 

def login(request, year, month): 
    if request.method == 'GET':
        return render(request, 'login.html')
 

 

有名分组(按关键字传参) 

用re_path方法,在url里用小括号进行分组(括号里写上正则的规则).

语法: 括号里 (?P<关键字名称>正则规则)

1 re_path(r'^login/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})$', views.login)

 

在视图函数中必须跟关键字名称保持一致,位置没有关系

1 def login(request, year, month):
2     print(year, month)
3     return render(request, 'login.html')

 

反向解析

在使用Django 项目时, 一个常见的需求是获得URL的最终形态, 以用于显示到内容中视图中和显示给用户的URL等)或者用于处理服务器端的导航(重定向等)。人们强烈希望不要硬编码这些URL(费力、不可扩展且容易产生错误)或者设计一种与URLconf 毫不相关的专门的URL 生成机制,因为这样容易导致一定程度上产生过期的URL。
好处: 当你url发生改变,动态反向解析出对应的url.便于开发和维护.

使用的步骤: 

  • urls.py 定义name
path('login/', views.login, name='login')

 

  • 在 views.py中反向解析
from django.urls import reverse

reverse("login")

#无名分组
#re_path(r'^login1/([0-9]{2})/$', views.login, name="login"),
reverse("login", args=("12",))

#有名分组
#re_path(r'^login1/(?P<month>[0-9]{2})/$', views.login, name="login"),
reverse("login", kwargs={"month": "12"})

 

  • 在模板login.html中使用反向解析
1 path方法(url)
2 <form action="{% url 'login' %}" method="post">
3     
4 re_path(无名分组)
5 <form action="{% url 'login' 12 %}" method="post">
6     
7 re_path(有名分组)
8 <form action="{% url 'login' month=12 %}" method="post">

 

路由分发

  在我们的django项目中,往往有很多的app, 我们的views和models文件都放在了对应的app中, 但我们的url却在项目目录下,若我们的app下有很多条url, 难不成都放在urls文件中,这样虽然也行,但是耦合度太高了,后期修改的话也很麻烦,所以django在url这里给你提供了一个分发接口,叫做include

使用include实现路由分发

总路由下的urls.py

from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'app01', include('app01.urls'), 
]

app01的urls.py的内容:(其实就是将全局的urls.py里面的内容copy一下,放到你在app01文件夹下创建的那个urls.py文件中,把不是这个app01应用的url给删掉就行了)

app01下的urls.py

urlpatterns = [
    url(r'^articles/2003/', views.special_case_2003,{'foo':'xxxxx'}), #{'foo':'xxxxx'}那么你的视图函数里面必须有个形参叫做foo来接收这种传参
    url(r'^articles/(\d{4})/(\d{2})/', views.year_archive),
]

此时当我们在访问我们的相关路径时,就要加上app01了

 

 

名称空间

命名空间(英语:Namespace)是表示标识符的可见范围。一个标识符可在多个命名空间中定义,它在不同命名空间中的含义是互不相干的。这样,在一个新的命名空间中可定义任何标识符,它们不会与任何已有的标识符发生冲突,因为已有的定义都处于其它命名空间中。
我们在开发项目时,会经常使用name属性反解出URL,当不小心在不同的app的urls中定义相同的name时,可能会导致URL反解错误,为了避免这种事情发生,引入了命名空间。

  • 定义名称空间

  project的urls.py  

path('app01/', include(("app01.urls", namespace="app01"))),
path('app02/', include(("app02.urls", "app02"))),    # 可以省略namespace
  • 使用名称空间

  • app01.urls 
1 urlpatterns = [
2     re_path(r'^index/', index,name="index"),
3 ]

 

  • app02.urls

    1 urlpatterns = [
    2     re_path(r'^index/', index,name="index"),
    3 ]
  • app01.views

    1 from django.core.urlresolvers import reverse
    2 
    3 def index(request):
    4   num = 12   # 如果重定向的下一个地址需要参数,所以定义个num访问
    5     return  redirect(reverse("app01:index", args(num,)))
  • app02.views

    1 from django.core.urlresolvers import reverse
    2 
    3 
    4 def index(request):
    5     return  HttpResponse(reverse("app02:index"))
  • 在模板中也是同理

    1 <form action="{% url 'app01:Login' 11 %}" method="post">  <!--这里的11 是路径后面携带的参数-->
    2     <p>用户名:<input type="text" name="user"></p>
    3     <p>密码:<input type="password" name="pwd"></p>
    4     <input type="submit">
    5 </form>

关于 路径中的 / 

1 urlpatterns = [
2     url(r'^admin/', admin.site.urls),
3     url('home/', views.home),
4     # url('^$', include('home.urls'))
5 ]

 

注意: 这里我们请求 127.0.0.1:8000/home 但是如图也访问成功了,这是因为浏览器自动帮我们加上了斜杆 

当我们访问home时然后帮我们重定向到 home/

 

 

 

 若我们不想让浏览器帮我们自动加斜杠可在settings中配置

1 APPEND_SLASH = False # 加上斜杠

 

 

 当我们再次访问时: 

 

 

posted @ 2020-11-23 16:34  死里学  阅读(69)  评论(0)    收藏  举报