美文网首页
2018-12-29

2018-12-29

作者: Karl_2c80 | 来源:发表于2019-01-02 15:18 被阅读0次

    FBV & CBV

    FBV (Function-Based-View):在视图里使用函数处理请求
    CBV (Class-Based-View):在视图里使用类处理请求

    # views.py
    from django.http import HttpResponse
    from django.views import View
      
    class MyView(View):
    
          def get(self, request):
                return HttpResponse('OK, get')
    
          def post(self, request):
                return HttpResponse('OK, post')
    
    # Django的url是将一个请求分配给可调用的函数的,而不是一个class。
    # 针对这个问题,class-based view提供了一个as_view()静态方法(也就是类方法),调用这个方法,会创建一个类的实例,然后通过实例调用dispatch()方法,dispatch()方法会根据request的method的不同调用相应的方法来处理request(如get() , post()等)。
    # 到这里,这些方法和function-based view差不多了,要接收request,得到一个response返回。如果方法没有定义,会抛出HttpResponseNotAllowed异常。
    
    # urls.py
    # urls.py
    from django.conf.urls import url
    from myapp.views import MyView
      
    urlpatterns = [
         url(r'^index/$', MyView.as_view()),
    ]
    
    • 类的 属性 可以通过两种方法设置
      (1) 常见的Python的方法,可以被子类覆盖。
    from django.http import HttpResponse
    from django.views import View
      
    class GreetingView(View):
        name = "yuan"
        def get(self, request):
             return HttpResponse(self.name)
      
    # You can override that in a subclass
      
    class MorningGreetingView(GreetingView):
        name= "alex"
    

    (2) url中设置类的属性

    urlpatterns = [
       url(r'^index/$', GreetingView.as_view(name="egon")),
    ]
    

    应用:登录验证

    ----------------应用:登录验证
       
       继承:
            单继承:
                # class BaseView(View):
                #     def dispatch(self, request, *args, **kwargs):
                #         if request.session.get('username'):
                #             response = super(BaseView,self).dispatch(request, *args, **kwargs)
                #             return response
                #         else:
                #             return redirect('/login.html')
                #
                # class IndexView(BaseView):
                #
                #     def get(self,request,*args,**kwargs):
                #         return HttpResponse(request.session['username'])
    写一个类继承VIEW 调用View 的dispath 函数之前做一个 session验证
    
    多继承:
    
    # 多继承方式:
    # class BaseView(object):
    #     def dispatch(self, request, *args, **kwargs):
    #         if request.session.get('username'):
    #             response = super(BaseView,self).dispatch(request, *args, **kwargs)
    #             return response
    #         else:
    #             return redirect('/login.html')
    #
    # class IndexView(BaseView,View):
    #
    #     def get(self,request,*args,**kwargs):
    #         return HttpResponse(request.session['username'])
    
    和上面的方法原理相同, 自己写的类BaseView不继承任何类, 然后主类 继承 自己写的类 和 View 类,BaseView中的super方法 会找到 View 中的dispath 
    
    装饰器:
       
       def auth(func):
          def inner(request,*args,**kwargs):
             if request.session.get('username'):
                obj = func(request,*args,**kwargs)
                return obj
             else:
                return redirect('/login.html')
          return inner
    
       
       # @method_decorator(auth,name='get')
       class IndexView(View):
          
          @method_decorator(auth)
          def dispatch(self, request, *args, **kwargs):
             if request.session.get('username'):
                response = super(IndexView,self).dispatch(request, *args, **kwargs)
                return response
             else:
                return redirect('/login.html')
    
          @method_decorator(auth)
          def get(self,request,*args,**kwargs):
             return HttpResponse(request.session['username'])
             
          @method_decorator(csrf_exempt)  # 无效
          def post(self,request,*args,**kwargs):
             return HttpResponse(request.session['username'])
    要注意俩点:
        1:用的 CBV 的话 需要导入 from django.utils.decorators import method_decorator  之后@method_decorator(auth)
        放在函数名上,   如果放在类上需要加个参数  @method_decorator(auth,name='get') ,说明是 给 get函数使用 
       2:但是django有个BUG 装饰器方法都会出现 CSRF问题 ,所以
        需要写一个dispath方法 直接调用VIEW里面的 dispath 进行反射@method_decorator(auth) 放在 dispath上面
    

    serializers序列化

    • json.dumps():将字典转为字符串
    • serializers.serialize():将QuerySet等类型转为字符串
       方式一:
          user_list = models.UserInfo.objects.all()
          data = serializers.serialize("json", user_list)
          [
             {"model": "app01.userinfo", "pk": 1, "fields": {"username": "\u5174\u666e", "password": "123123"}}, 
             {"model": "app01.userinfo", "pk": 2, "fields": {"username": "\u94f6\u79cb\u826f", "password": "666"}}
          ]
    
    由于json.dumps 不能对 QuerySet 类型进行处理, 所以 要使用 serializers.serialize  ;但是处理结果往往不太理想
    
          
       方式二:
          
          user_list = models.UserInfo.objects.values('id','username')
          user_list = list(user_list)
          data = json.dumps(user_list)
          [
             {"username": "\u5174\u666e", "id": 1}, 
             {"username": "\u94f6\u79cb\u826f", "id": 2}
          ]
      所以我们可以 用list 将QuerySet 类型转变为List类型
          
          问题:对json.dumps做定制:
    
      如果要json的列表中有不能处理的字段类型,比如datetime,date
      那么就需要帮它们转换一下,
      在json.dumps 的命令中 可以多增加一个参数,cls=一个类
      这个类继承 json.JSONEncoder,如下
             
                import json
                from datetime import date
                from datetime import datetime
    
                class JsonCustomEncoder(json.JSONEncoder):
                   def default(self, field):
                      if isinstance(field, datetime):
                         return field.strftime('%Y-%m-%d %H:%M:%S')
                      elif isinstance(field, date):
                         return field.strftime('%Y-%m-%d')
                      else:
                         return json.JSONEncoder.default(self, field)
    
    
                user_list = [
                   {'id':1,'name':'alex','ctime': datetime.now()},
                   {'id':2,'name':'eric','ctime': datetime.now()}
                ]
    
                data = json.dumps(user_list,cls=JsonCustomEncoder)
                print(data)
    就可以帮助我们处理 datetime,date类型了,其他类型,当然也可以,修改类里面就ok
    

    相关文章

      网友评论

          本文标题:2018-12-29

          本文链接:https://www.haomeiwen.com/subject/iukzlqtx.html