• 五、Django 路由配置


    URLconf

    Django的项目文件夹和每个应用(app)目录下都有urls.py文件,它们构成了Django的路由配置系统(URLconf)。服务器收到用户请求后,会根据用户请求的url地址和urls.py里配置的url-视图映射关系,去调用执行相应的视图函数或视图类,最后由视图返回给客户端数据。

    假如有一个blog的博客应用,需要编写两个视图函数,一个用于展示文章列表,一个用于展示文章详情,urls.py和views.py正常情况下应如下所示:

    # blog/urls.py
    from django.urls import path
    from . import views
     
    urlpatterns = [
        path('blog/', views.index),
        path('blog/articles//', views.article_detail),
    ]
     
    # blog/views.py
    def index(request):
        # 展示所有文章
       
    def article_detail(request, id):
        # 展示某篇具体文章
    

    如何工作的呢?

    • 当用户在浏览器输入/blog/时,URL收到请求后会调用视图views.py里的index方法,展示所有文章
    • 当用户在浏览器输入/blog/article/int:id/时,URL不仅调用了views.py里的article_detail方法,而且还把参数文章id通过<>括号的形式传递给了视图。int这里代表只传递整数,传递的参数名字是id。
    • 在上述代码中,我们通过urlpatterns列表的url-视图映射关系列表起了决定性作用,起到了任务调度的作用。

    注意:注意当你配置URL时,别忘了把你的应用(blog)的urls加入到项目的URL配置里(mysite/urls.py), 如下图所示:

    from django.urls import include, path
    
    urlpatterns = [
        path('', include('blog.urls')),
        ...
    ]
    

    path和re_path方法

    写个URL很简单,但如何通过URL把参数传递给给视图view是个技术活。Django提供了两种设计URL的方法: path和re_path,它们均支持向视图函数或类传递参数。path是正常参数传递,re_path是采用正则表达式regex匹配。path和re_path传递参数方式如下:

    • path方法:采用双尖括号<变量类型:变量名>或<变量名>传递,例如int:id, slug:slug或。

    • re_path方法: 采用命名组(?P<变量名>表达式)的方式传递参数。

    下例中,我们分别以path和re_path 定以了两个urls,它们是等效的,把文章的id(整数类型)传递给了视图。re_path里引号前面的小写r表示引号里为正则表达式, ^代表开头,$代表以结尾,\d+代表正整数。

    # blog/urls.py
    from django.urls import path, re_path
    from . import views
     
    urlpatterns = [
        path('blog/articles//', views.article_detail, name = 'article_detail'),
        re_path(r'^blog/articles/(?P\d+)/$', views.article_detail, name='article_detail'),
    ]
     
    # blog/views.py
    def article_detail(request, id):
        # 展示某篇文章
    

    在使用path和re_path方法设计urls需注意:

    • url中的参数名要用尖括号,而不是圆括号;
    • 匹配模式的最开头不需要添加斜杠/,但建议以斜杠结尾;
    • 使用re_path时不一定总是以$结尾,有时不能加。比如下例中把blog.urls通过re_path加入到项目urls中时就不能以$结尾,因为这里的blog/并不是完整的url,只是一个开头而已。
    from django.urls import include, re_path
    
    urlpatterns = [
        re_path(r'^blog/', include('blog.urls')),
        ...
    ]
    

    URL配置示例

    path支持匹配的数据类型只有str,int, slug, uuid四种。一般来说re_path更强大,但写起来更复杂一些,我们来看看更多案例

    # 示例一,PATH
    from django.urls import path
    from . import views
    
    urlpatterns = [
        path('articles/2003/', views.special_case_2003),
        path('articles//', views.year_archive),
        path('articles///', views.month_archive),
        path('articles////', views.article_detail),
    ]
    
    # 示例二:RE_PATH,与上例等同
    from django.urls import path, re_path
    from . import views
    
    urlpatterns = [
        path('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[\w-]+)/$', views.article_detail),
    ]
    

    示例一,PATH

    from django.urls import path
    from . import views
    
    urlpatterns = [
        path('articles/2003/', views.special_case_2003),
        path('articles//', views.year_archive),
        path('articles///', views.month_archive),
        path('articles////', views.article_detail),
    ]
    

    示例二:RE_PATH,与上例等同

    from django.urls import path, re_path
    from . import views
    
    urlpatterns = [
        path('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[\w-]+)/$', views.article_detail),
    ]
    

    URL的命名及reverse()方法

    使用命名URL

    {% for article in articles %}
        <a href="{% url 'article_detail' article.id %}">{{ article.title }}</a>
    {% endfor %}
    

    url是个模板标签,其作用是对命名的url进行方向解析,动态生成链接。

    注意:命名的url里有几个参数,使用url模板标签反向生成动态链接时,就需要向它传递几个参数。比如我们的命名urlarticle_detail里有整数型id这个参数,我们在模板中还需要传递article.id。

    使用命名URL

    {% for article in articles %}
        <a href="{% url 'article_detail' article.id %}">{{ article.title }}</a>
    {% endfor %}
    

    url是个模板标签,其作用是对命名的url进行方向解析,动态生成链接。

    注意:命名的url里有几个参数,使用url模板标签反向生成动态链接时,就需要向它传递几个参数。比如我们的命名urlarticle_detail里有整数型id这个参数,我们在模板中还需要传递article.id。

    Django提供的reverse()方法很容易实现这点。它在视图中可以对命名urls进行反向解析,生成动态链接。

    from django.urls import reverse
    
    output blog/articles/id
    reverse('blog:article_detail', args=[id]) 
    

    URL指向基于类的视图(View)

    目前path和re_path都只能指向视图view里的一个函数或方法,而不能直接指向一个基于类的视图(Class based view)。Django提供了一个额外as_view()方法,可以将一个类伪装成方法。这点在当你使用Django自带的类视图或自定义的类视图时非常重要。
    具体使用方式如下:

    #blog/urls.py
    from django.urls import path, re_path
    from . import views
     
    urlpatterns = [
        # path('blog/articles/', views.article_list, name = 'article_list'),
        path('blog/articles/', views.ArticleList.as_view(), name='article_list'),
    ]
     
    #View (in blog/views.py)
    from django.views.generic import ListView
    from .views import Article
     
    class ArticleList(ListView):
        queryset = Article.objects.filter(date__lte=timezone.now()).order_by('date')[:5]
        context_object_name = 'article_list‘
        template_name = 'blog/article_list.html'
    

    通过URL传递额外的参数

    在你配置URL时,你还可以通过字典的形式传递额外的参数给视图, 而不用把这个参数写在链接里。如下面案例所示:

    # blog/urls.py
    from django.urls import path, re_path
    from . import views
     
    urlpatterns = [
        path('', views.ArticleList.as_view(), name='article_list', {'blog_id': 3}),
    ]
    
  • 相关阅读:
    Spring Boot : ORM 框架 JPA 与连接池 Hikari
    Wintel联盟忙着定义AI PC,但各做了一半
    红米手机 导出 通讯录 到电脑保存
    QProcess类
    C++运算符重载详解(日期类实操)
    1743. 从相邻元素对还原数组-哈希表法
    python脚本打包apk-上传到内测平台-企业微信通知
    软件测试 -- 进阶 4 软件测试策略
    【车联网/自动驾驶仿真学习】VEINS_CARLA安装指南
    【网络数据采集】python爬取豆瓣top250电影目录
  • 原文地址:https://blog.csdn.net/D_A_I_H_A_O/article/details/142091988