欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Django基础第六天-视图层

程序员文章站 2022-03-23 12:27:20
...

相对于Django2.0版本中的path

2.x版本中的re_path与1.x版本中的url功能一样
示例:

urlpatterns = [  
    re_path('articles/(?P<year>[0-9]{4})/', year_archive),  
    re_path('article/(?P<article_id>[a-zA-Z0-9]+)/detail/', detail_view),  
    re_path('articles/(?P<article_id>[a-zA-Z0-9]+)/edit/', edit_view),  
    re_path('articles/(?P<article_id>[a-zA-Z0-9]+)/delete/', delete_view),  
]

考虑下这样的两个问题:

第一个问题,函数 year_archive 中year参数是字符串类型的,因此需要先转化为整数类型的变量值,当然year=int(year) 不会有诸如如TypeError或者ValueError的异常。那么有没有一种方法,在url中,使得这一转化步骤可以由Django自动完成?

第二个问题,三个路由中article_id都是同样的正则表达式,但是你需要写三遍,当之后article_id规则改变后,需要同时修改三处代码,那么有没有一种方法,只需修改一处即可?

在Django2.0中,可以使用 path 解决以上的两个问题。

案例示范:

from django.urls import path  
from . import views  
urlpatterns = [  
    path('articles/2003/', views.special_case_2003),  
    path('articles/<int:year>/', views.year_archive),  
    path('articles/<int:year>/<int:month>/', views.month_archive),  
    path('articles/<int:year>/<int:month>/<slug>/', views.article_detail),  

  # path才支持,re_path不支持
  path('order/<int:year>',views.order),
]

基本规则:

  • 使用(<>)从url中捕获值。
  • 捕获值中可以包含一个转化器类型(converter type),比如使用 <int:name> 捕获一个整数变量。若果没有转化器,将匹配任何字符串,当然也包括了 / 字符。
  • 无需添加前导斜杠。

以下是根据 2.0官方文档 而整理的示例分析表:(跟上面url的匹配关系)

Django基础第六天-视图层

path转化器

根据官方文档Path converters翻译为转化器

Django默认支持以下5个转化器:

  • str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
  • int,匹配正整数,包含0。
  • slug,匹配字母、数字以及横杠、下划线组成的字符串。
  • uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
  • path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)

对于2.x的path使用方法及注意点:
1 在url.py文件中,from django.urls import path
    2 不支持正则,精准匹配
    3 有5个转换器(int,str,slug,path,uuid)
    4 自定义转换器步骤:
        1 写一个类:
          class Test:
              regex = '[0-9]{4}'
              def to_python(self, value):
                  # 写一堆处理
                  value=value+'aaa'
                  return value
              def to_url(self, value):
                  return '%04d' % value
        2 from django.urls import register_converter
        3 register_converter(Test,'ttt')
        4 path('index/<ttt:year>', views.index,name='index'),

注册自定义转化器

对于一些复杂或者复用的需要,可以定义自己的转化器。转化器是一个类或接口,它的要求有三点:

  • regex 类属性,字符串类型
  • to_python(self, value) 方法,value是由类属性 regex 所匹配到的字符串,返回具体的Python变量值,以供Django传递到对应的视图函数中。
  • to_url(self, value) 方法,和 to_python 相反,value是一个具体的Python变量值,返回其字符串,通常用于url反向引用。

举例:

class FourDigitYearConverter:  
    regex = '[0-9]{4}'  
    def to_python(self, value):  
        return int(value)  
    def to_url(self, value):  
        return '%04d' % value  

使用register_converter 将其注册到URL配置中:

from django.urls import register_converter, path  
from . import converters, views  
register_converter(converters.FourDigitYearConverter, 'yyyy')  
urlpatterns = [  
    path('articles/2003/', views.special_case_2003),  
    path('articles/<yyyy:year>/', views.year_archive),  
    ...  
]

 

Django之视图层

1 什么视图函数

一个视图函数,简称为视图,是一个简单的Python函数,它接受Web请求并且返回Web响应。响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档或者一张图片...是任何东西都可以。无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你的Python目录下面。除此之外没有更多的要求了— —可以说“没有什么神奇的地方”。为了将代码放在某处,约定是将视图放置在项目或应用程序目录中的名为views.py的文件中.

下面是一个返回当前日期和时间作为HTML文档的视图:

from django.shortcuts import render, HttpResponse, HttpResponseRedirect, redirect
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)
  • 首先,我们从 django.shortcuts模块导入了HttpResponse类,以及Python的datetime库。

  • 接着,我们定义了current_datetime函数。它就是视图函数。每个视图函数都使用HttpRequest对象作为第一个参数,并且通常称之为request。

    注意,视图函数的名称并不重要;不需要用一个统一的命名方式来命名,以便让Django识别它。我们将其命名为current_datetime,是因为这个名称能够精确地反映出它的功能。

  • 这个视图会返回一个HttpResponse对象,其中包含生成的响应。每个视图函数都负责返回一个HttpResponse对象。

视图层,熟练掌握两个对象即可:请求对象(request)和响应对象(HttpResponse) 

MVC和MTV        
        M                  T                      V                        

        models         template         views

        M                   V                    C(路由+views)
        models         模板                控制器

 视图层:request对象:
    # form表单,不写method ,默认是get请求
    #     1 什么情况下用get:请求数据,请求页面,
    #     2 用post请求:向服务器提交数据
    # request.GET  字典
    # request.POST  字典
    # 请求的类型
    # print(request.method)
    # 路径
    # http://127.0.0.1:8000/index/ppp/dddd/?name=lqz
    # 协议:ip地址和端口/路径?参数(数据)  
    # print(request.path)
    # print(request.get_full_path())

CBV 基于类的视图(class base view)和FBV 基于函数的视图(function base view)
    cbv:
        1 from django.views import View
        2 class Test(View):
            def dispatch(self, request, *args, **kwargs):
                # 加点东西
                print('111')

                obj=super().dispatch(request, *args, **kwargs)
                # 加点东西
                print('2222')
                return obj
            def get(self,request):
                obj= render(request,'index.html')
                print(type(obj))
                return obj
            def post(self,request):
                return HttpResponse('ok')
        3 re_path(r'index/', views.Test.as_view()),

 简单文件上传
    1 <form action="" method="post" enctype="multipart/form-data">
        用户名:<input type="text" name="name">
        密码:<input type="text" name="password">
        文件:<input type="file" name="myfile">
        <input type="submit">
    
        </form>
        #enctype="multipart/form-data"*******************
        #<input type="file" name="myfile">
        
    2   # ff是一个文件对象,django封装的
        ff=request.FILES.get('myfile')
        # 文件对象的名字
        file_name=ff.name
        from django.core.files.uploadedfile import InMemoryUploadedFile
        print(type(ff))
        with open(file_name,'wb') as f:
            for line in ff.chunks():
                f.write(line)

相关标签: Django