• Django_URL


    视图函数介绍

    视图一般都写在app的views中,并且视图的第一个参数永远都是request(HttpRequest)对象。这个对象存储了请求过来的所有信息,包括携带的参数以及一些头部信息等。再视图中,一般完成逻辑相关的操作,比如这个请求是添加一篇博客,那么可以通过request来接收到这些数据,然后存储到数据库中,最后再把执行的结果返回给浏览器。

    视图函数的返回结果必须是HttpResponseBase对象或者HttpResponseBase子类的对象。

    django与flask传递参数区别:flask不需要传递这个request,是一个全局变量,django的request必须传递过来才能使用;

    from django.http import HttpResponse
    
    def index(request):
        return HttpResponse(u"花花")

    URL映射

    1.为什么回去urls.py文件中寻找映射呢?

    因为在settings.py中配置了ROOT_URLCONF为urls.py:

    ROOT_URLCONF = 'first.urls'

    2.在urls.py中我们所有的映射都应该放在urlpatterns这个变量中

    urlpatterns = [
        path('admin/', admin.site.urls),
    ]

    3.所有的映射不是随便写的,而是通过path函数或者re_path函数进行包装的。

    path = partial(_path, Pattern=RoutePattern)
    re_path = partial(_path, Pattern=RegexPattern)

    4、默认首页映射查找

    在没有写任何url映射时,django会给到一个默认的页面,如果一旦有映射其他url页面,就要写个视图函数,url映射到空字符串,给到一个首页;

    urlpatterns = [
        path('admin/', admin.site.urls),
        re_path(r'',views.index),
    ]

    URL中传递参数给视图函数

    1、采用在url中使用变量的方式

    在path的第一个参数中,使用<参数名>的方式可以传递参数。然后在视图函数中也要写一个参数,视图函数中的参数必须和url中的参数名称保持一致,不然就找不到这个参数。另外,url中可以传递多个参数

    views.py

    from django.http import HttpResponse
    
    def index(request):
        return HttpResponse(u"花花首页")
    
    def book(request):
        return HttpResponse("图书")
    
    def book_detail(request,book_id,category_id):
        text = "您获取的图书id是:%s,图书分类是%s" % (book_id,category_id)
        return HttpResponse(text)

    urls.py

    from django.contrib import admin
    from django.urls import path,re_path
    from cmdb import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path(r'',views.index),
        path(r'book/',views.book),
        path(r'book_detail/<book_id>/<category_id>/',views.book_detail),
    ]

    结果:

    2、采用查询字符串的方式

     在url中,不需要单独的匹配查询字符串的部分。只需要在视图函数中使用request.GET.get('参数名称')的方式来获取。示例代码如下:

    path('book_author/',views.author_detail),
    
    
    def author_detail(request):
        author_id = request.GET['id']         #request包括客户端和浏览器请求过来的所有数据
        text = '作者的id是:%s' % author_id
        return HttpResponse(text)

    访问:http://127.0.0.1:8000/book_author/?id=2 即可将参数传递过去。

    因为查询字符串使用的是`GET`请求,所以我们通过`request.GET`来获取参数。并且因为`GET`是一个类似于字典的数据类型,所有获取值跟字典的方式都是一样的。

    django内置的URL转换器

    1、如何限制参数类型:

    可以使用django内置的url转换器(converters)。我们可以从converters包中了解所有的转换器,首先在urls.py中导入urls包引入转换器,(快速打开converters.py方法:写一行 "from django.urls import converters" 鼠标放在converters下ctrl+b)

    from django.urls import converters

    打开converters.py后可以了解到所有的转换器:

    2、类型总结:

    int类型:1个或者多个0-9的数字;

    str类型:除了/其余都可以作为str类型,默认时str转换器;

    uuid类型:uuid转换器具有唯一性,只满足uuid.uuid4()类型的 ,如:923c3f5f-edeb-4d2b-ac70-a99eb4425b0b(print(uuid.uuid4()));

    slug类型:数字、大小写字母、-满足,其余不行;

    path类型:str转换器不能有/ 而path转换器是可以包含任意字符的,包括/;

    3、格式规范

    只要在url,path中<参数名>前加格式类型即可

    path(r'publisher_detail/<int:publisher_id>/',views.publisher_detail),   #参数名前面加上格式类型
    
    
    def publisher_detail(request,publisher_id):
        text = '出版社的id是:%s' % (publisher_id)
        return HttpResponse(text)

    4、如何生成uuid?

    进入python函数,uuid是python内置库
    >>> import uuid
    >>> print(uuid.uuid4())
    74858df0-7b95-4366-ae6c-dc54aa9402c6      #自动生成uuid
    >>>

     url分层模块化

     当项目越来越大,url也会变得越来越多。如果放在主"urls.py"文件中,将会不好管理。因此我们可以将每个app自己的urls放在自己的app中进行管理,一般我们会在app中新建一个urls.py文件用来存储所有和此app相关的url。

    1、在app文件夹下新建一个urls.py文件,并写入相关app的urls,注意要import 视图函数

    from django.urls import path
    from . import views
    
    urlpatterns = [
    
        path(r'',views.book),    
        path(r'detail/<book_id>/<category_id>/',views.book_detail),
        path('author/',views.book_author),
        path(r'publisher/<int:publisher_id>/',views.book_publisher),  ##参数名前面加上格式类型
    ]

    2、在主urls.py中调入app的url

    from django.urls import path,include  #导入include模块
    
    
        path(r'',include('cmdb.urls')),     #这边我写个空代表会找到urls表里的第一个path映射的view
        path('book/',include('cmdb.urls')),  
    #url是会根据主 urls.py 和 app中的 urls.py 进行拼接,因此这边book加了'/',app中的拼接前面就不需要加'/'了

    3、需要注意的地方:

    1) url模块化是为了方便管理,即将每个APP中各建立自己的urls.py文件 。
    2) 在项目下有一个总的urls.py文件,这个文件的主要作用是将每个APP去找各自的urls.py文件,在该文件中,应该使用include函数包含urls.py,且是相对于项目路径 。
    3) 在APP中的urls.py文件,所有的匹配也应该放在urlpatterns中 。
    4) 最终的url是根据主url.py和APP的url.py进行拼接的,因此,不可多加或少加/。

    URL命名与反转URL

    1.新建一个项目 在项目中创建cms和fomt两个app。
    2. 在cms应用的views.py文件里输入如下代码:

    from django.http import HttpResponse
    
    def index(request):
        return HttpResponse('CMS首页')
    
    def login(request):
        return HttpResponse('CMSlogin登录页面')

    3. 在fomt应用的views.py文件里输入如下代码:

    from django.http import HttpResponse
    
    def index(request):
        return HttpResponse('前台首页')
    
    def login(request):
        return HttpResponse('前台登录页面')

    4. 在cms和fomt两个app里各创建一个urls.py文件,分别写下文件中代码如下:

    from django.urls import path
    from . import views
    
    urlpatterns = [
        path('',views.index),
        path('login/',views.login),
    ]

    5. 在项目的urls.py文件中更新代码如下:

    from django.urls import path,include
    
    urlpatterns = [
        #path('admin/', admin.site.urls),
        path('',include('fomt.urls')),
        path('cms/',include('cms.urls')),
    ]

    6. 实现url反转
    调整fomt应用views.py里的代码,实现未登陆用户调转到登陆页面的功能。
    调整后的代码如下:

    from django.shortcuts import render
    from django.http import HttpResponse
    from django.shortcuts import redirect #redirect重定向
    
    def index(request):
        username = request.GET.get('username')  #获取查询字符串
        if username:
            return HttpResponse('前台首页')
        else:
            return redirect('/login/')   #重定向到登录页面
    
    def login(request):
        return HttpResponse('前台登录页面')

     访问127.0.0.1:8000 直接跳转到前台登录页面

     访问http://127.0.0.1:8000/?username=huahua  跳转到前台首页

    7. url命名

    为什么需要给url命名?

    因为url是经常变化的。如果在代码中写死可能会经常改代码。给url取个名字,以后使用url的时候就使用他的名字进行反转就可以了,就不需要写死url了。

    在fomt应用中views.py代码修改如下:

    from django.http import HttpResponse
    from django.shortcuts import redirect,reverse #redirect重定向  ,增加了reverse函数
    
    def index(request):
        username = request.GET.get('username')  #获取查询字符串
        if username:
            return HttpResponse('前台首页')
        else:
            login_url=reverse('login')   #urls.py中的url的name
    
            print(login_url)#在控制台可查看打印的东西
            return redirect(login_url)   # 将login反转的url赋值给login_url
    
    def login(request):
        return HttpResponse('前台登录页面')

    如何给url指定名称?

    在'path'函数中,传递一个'name'参数可以指定。

    在front应用中urls.py代码修改如下:

    from django.urls import path
    from . import views
    
    urlpatterns = [
        path('',views.index,name='index'),
        path('signin/',views.login,name='login'),
    ]   # 后期如果想将login改为signin,只需要将前面的“login/”修改为“signin/”即可,别的不用动。

    访问http://127.0.0.1:8000/自动跳到http://127.0.0.1:8000/signin/前台登录页面;

    应用(app)命名空间

    在多个app之间,有可能产生同名的url。这时候为了避免反转url的时候产生混淆,可以使用应用命名空间,来做区分。定义应用命名空间非常简单,只要在app的urls.py中定义一个叫做app_name的变量,来指定这个应用的命名空间即可。

    ’cms’的app应用views.py文件中给url命名:

    from django.urls import path
    from . import views
    
    urlpatterns = [
        path('',views.index,name = 'index'),
        path('login',views.login,name = 'login'),
    ]

    访问:http://127.0.0.1:8000/cms/login

    发现跳转至了cms登录页面去了,而我们是想让他跳转至前台登录页面啊!
    这是因为我们现在的项目中有两个app,在这两个app中我们都将各自的主页url取名为‘index’,登录页面也都是命名为’login’,在

    return redirect( reverse('login') )

    进行反转的时候,Django不能准确的找到需要跳转的页面,所以他就会跳转至找到的第一个’login’的页面。这个时候我们就需要让Django明确的知道需要跳转的页面,所以我们在每个app中的urls.py中添加一个变量app_name

    1、fomt中的urls.py中添加:

    #应用命名空间
    #应用命名空间的变量叫做app_name
    app_name = 'fomt'

    2、在cms中的urls.py中添加:

    app_name = 'cms'

    3、然后我们需要明确的指出需要跳转的页面,在front中的views.py中的index函数修

    这样以后左反转的时候就可以使用'应用命名空间:url名称'的方式进行反转;

    def index(request):
        username = request.GET.get('username') 
        if username:
            return HttpResponse('前台首页')
        else:
            login_url=reverse('fomt:login')   #urls.py中的url的name
            return redirect(login_url)

    访问:http://127.0.0.1:8000 这样Django就明确的知道需要跳转至哪一个页面了。

    实例命名空间

    一个app,可以创建多个实例。即可以使用多个url映射同一个app。所以这就会产生一个问题。以后在做反转的时候,如果使用应用命名空间,那么就会发生混淆。为了避免这个问题。我们可以使用实例命名空间。实例命名空间也是非常简单,只要在include函数中传递一个namespace变量即可。
    1.在主urls.py中对cms添加两个映射,然后实例化命名

    from django.urls import path,include
    
    urlpatterns = [
        #path('admin/', admin.site.urls),
        path('',include('fomt.urls')),
        path('cms1/',include('cms.urls',namespace='cms1')),
        path('cms2/',include('cms.urls',namespace='cms2')),
    ]

    2.然后修改下cms的views.py中index函数的代码,没有传入用户名进来时直接跳转至登录页面

    from django.shortcuts import reverse,redirect
    def index(request):
        username = request.GET.get("username")
        if username:
            return HttpResponse('CMS首页')
        else:
            # 获取当前的命名空间
            current_namespace = request.resolver_match.namespace
            return redirect(reverse("%s:login" % current_namespace))

    们就使用cms1进入时,就会进入cms1的登录页面,使用cms2进入,就会进入cms2的登录页面,http://127.0.0.1:8000/cms2/login  

     include函数用法

    1、include(module,namespace = None)

    module:子url的模块字符串;

    namespace:实例命名空间,如果指定实例命名空间,前提必须要先指定应用命名空间,也就是在子'urls.py'中添加'app_name'变量‘

    2、includepattern_list:'pattern_list'是一个列表,这个列表中装的是'path'或者're_path'函数;

    3、include((pattern_list,app_namespace),namespace = None): include函数的第一个参数既可以为一个字符,也可以为一个元祖,如果是元组,那么元组的第一个参数是’urls.py‘

    模块的字符串,元组的第二个参数是应用命名空间,也就是说,应用命名空间既可以在子'urls.py'中通过'app_name'指定,也可以在'include'函数中指定; 

    re_path和path的区别

    1、re_path和path的作用都是一样的。只不过re_path是在写url的时候可以用正则表达式,功能更加强大。

    2、写正则表达式都推荐使用原生字符串。也就是以r开头的字符串。

    3、在正则表达式中定义变量,需要使用圆括号括起来。这个参数是有名字的,那么需要使用(?P<参数的名字>)。然后在后面添加正则表达式的规则。

    4、编写路由需要用的正则表达式,

    r 字符串前面加“ r ”是为了防止字符串中出现类似“ ”字符时被转义。

    ^ 匹配字符串开头;在多行模式中匹配每一行的开头。 ^abc abc

    $ 匹配字符串末尾;在多行模式中匹配每一行末尾

    例如:

    re_path(r"^list/(?P<year>d{4})/$",views.article_list),
    re_path(r"^list/(?P<month>d{2})/$",views.article_list_month)

    第一个表示以list开始,中间需要有4个数字,一个都不能多也不能少,再以 ‘/’ 结尾。
    形如list/2222/这样的字符窜才能被识别,
    同理,第二句是需要形如list/22/这样的字符窜才能被识别。
    例2:

    from django.urls import path,re_path
    
    urlpatterns = [
        re_path(r'^search_phone/$',views.search_phone),
        re_path(r'^sign_index/(?P<event_id>[0-9]+)/$', views.sign_index),
        re_path(r'^sign_index_action/(?P<event_id>[0-9]+)/$', views.sign_index_action),

    如果不是特别要求。直接使用path就够了,除非是url中确实是需要使用正则表达式来解决才使用re_path。

    reverse 函数补充

    1、如若在反转url时,需要添加参数,那么可以传递 kwargs 参数到 reverse 函数中,实例代码如下:

    views.py

    from django.shortcuts import render,reverse,redirect
    from django.http import HttpResponse
    
    
    def index(request):
        username = request.GET.get('username')
        if username:
            return HttpResponse('首页')
        else:
            detail_url = reverse('detail', kwargs={"article_id":'1'})  #使用 kwargs 参数到 reverse 函数中,也可添加多个参数;
            #detail_url = reverse('login') +"?next=/"
            return redirect(detail_url)
    
    
    def login (request):
        return HttpResponse('登录页面')
    
    def detail(request,article_id):
        text = '您的文章id是:%s' % article_id
        return HttpResponse(text)

    urls.py

    from django.urls import path
    from front import views
    
    urlpatterns = [
        path('', views.index),
        path('login/', views.login),
        path('detail/<article_id>', views.detail,name='detail'),
    ]

    2、如若想添加查询字符串参数,则必须手动进行url拼接,

    #detail_url = reverse('login') +"?next=/"

     指定默认参数

    使用path或者re_path时,在route中都可以包含参数,而有时想指定默认参数,通过以下方式完成

    url.py

    path('', views.books),
        path('book/<int:page>/', views.books),

    views.py

    from django.http import HttpResponse
    book_list=[
        '自动化',
        'python',
        'selenium'
    ]
    
    def books (request,page=0):
        return HttpResponse(book_list[page])

    当访问book的时候,因为没有传递page参数,所以会匹配到第一个url,这时候view.books这个视图函数,而在books函数中,又有page=0这个默认参数,因此这是就可以不用传递参数,而如果访问book/1的时候,因为在传递参数的时候传递了page,因此会匹配到第二个url,这时候也会执行views.books,然后把传递进来的参数传给books函数中的page。

  • 相关阅读:
    你知道怎么离线安装全局 node 模块吗?
    关于开发视图
    你知道 JavaScript 中的 Arguments 对象都有哪些用途吗?
    前端 JavaScript 实现一个简易计算器
    Docker 系列 _ 01_ 一念缘起
    机器学习资料大全
    pdf、txt文本复制到EXCEL后的格式快速调整法
    习惯的养成
    磁盘剩余空间监控
    please wait while windows configures microsoft visual studio professional 2013
  • 原文地址:https://www.cnblogs.com/huaerye/p/10576574.html
Copyright © 2020-2023  润新知