Django基础第六天-视图层

相对于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的匹配关系)

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)

猜你喜欢

转载自blog.csdn.net/qq_17513503/article/details/82427122