zoukankan      html  css  js  c++  java
  • day 59 JsonResponse,form表单上传文件,CBV,模版传值,过滤器,标签,自定义过滤器和标签,模版的的继承,模版的导入

    视图层函数返回数据方式:

    1.HttpResponse # 返回字符串

    2.render # 返回一个html页面 还可以给模板传值
    from django.template import Template,Context
    def index(request):
      res = Template("<h1> {{ user }} </h1>")
      con = Context({'user':{'username':'jason','pwd':'123'}})
      ret = res.render(con)
      print(ret)
      return HttpResponse(ret)
    3.redirect # 重定向


    JsonResponse
    返回json格式数据

    #为什么要给前端返回json格式字符串?
    前后端分离 就是基于json格式传输数据,后端就专门写接口,前端调用你这个接口 就能够拿到一个,json格式的字符串
    然后前端利用序列化反序列转换成前端对应的数据类型

    #js常用数据类型
      数值类型
      字符类型
      数组 []
      自定义对象 {}
      undefined与null
      布尔值 true false
      symbol

    JS中:
    JSON.stringify 序列化 >>> json.dumps
    JSON.parse 反序列 >>> json.loads

    # def index(request):
    # res = Template("<h1> {{ user }} </h1>")
    # con = Context({'user':{'username':'jason','pwd':'123'}})
    # ret = res.render(con)
    # print(ret)
    # return HttpResponse(ret)

    import json
    from django.http import JsonResponse

    def index(request):
    # user = {'username':'jason真帅 我好喜欢哦~','pwd':'123'}
    # json_str = json.dumps(user,ensure_ascii=False)
    # return HttpResponse(json_str)
    # return JsonResponse(user,json_dumps_params={'ensure_ascii':False}) #如果包含中文,需要将ensure_ascii设置为False
    l = [1,2,3,4,5,5,6]
    return JsonResponse(l,safe=False)
    # JsonResponse默认只支持序列化字典 如果你想序列化其他类型(json能够支持的类型) 你需要将safe参数由默认的True改成False



    form表单上传文件
    注意事项
    1.提交方式必须是post
    2.enctype参数必须有默认的urlencoded变成formdata

    <form action="" method="post" enctype="multipart/form-data">
    <input type="text" name="username">
    <input type="file" name="myfile">
    <input type="submit">
    </form>
    def up(request):
    if request.method == 'POST':
    print(request.POST)
    print(request.FILES)
    # 获取文件对象
    file_obj = request.FILES.get('myfile')
    print(file_obj.name) # 获取文件名
    with open(file_obj.name,'wb') as f:
    # for line in file_obj: # file_obj你可以直接看成文件句柄f
    for chunk in file_obj.chunks(): # file_obj你可以直接看成文件句柄f
    f.write(chunk)
    return render(request,'up.html')

    CBV
    FBV(Function Based View) 基于函数的视图
    CBV(Class Based View) 基于类的视图


    你在类中写了两个方法 一个叫get一个叫post,为什么前端get请求来就会触发get方法,post请求来就会触发post方法 如何实现的???

    # CBV路由
    url(r'^reg/',views.MyReg.as_view())

    #CBV源码分析
    @classonlymethod
    def as_view(cls, **initkwargs):
      def view(request, *args, **kwargs):
        self = cls(**initkwargs) # cls就是我们自己的写的MyReg类
        if hasattr(self, 'get') and not hasattr(self, 'head'):
          self.head = self.get
          self.request = request
          self.args = args
          self.kwargs = kwargs
          # 上面的一通操作 就是给我们自己写的类的对象赋值
        return self.dispatch(request, *args, **kwargs)
        # 对象在查找属性或方法的时候 顺序是什么? 先从自己找 再从产生对象的类中找 再去类的父类中找...
        """也就意味着你在看源码的时候 你一定要牢记上面的话"""
      return view


    # views.py
    from django.views import View

    class MyReg(View):
      def get(self,request):
        return render(request,'reg.html')

      def post(self,request):
        return HttpResponse("我是MyReg类中post方法")


    """CBV最精髓的部分"""
    def dispatch(self, request, *args, **kwargs):
      if request.method.lower() in self.http_method_names: # 判断当前请求方式在不在默认的八个请求方式中
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        # handler = getattr(自己写的类产生的对象,'小写的请求方法(getpost)','获取不到对应的方法就报错')
        # handler就是我们自己定义的跟请求方法相对应的方法的函数内存地址
      else:
        handler = self.http_method_not_allowed
      return handler(request, *args, **kwargs) # 在调用获取到的方法

    django settings源码分析及实际应用(你可以不掌握 但是我希望你掌握思路)

    django的配置文件有两个:
      一个是暴露给用户可以自定义配置的
      一个是默认的全局配置文件
      用户指定了就用用户的
      用户没有指定就用默认的

    from django.conf import settings

    settings = LazySettings()

    class LazySettings(LazyObject):

    def _setup(self, name=None):

    # os.environ你可以把它看成是一个全局的大字典
    settings_module = os.environ.get(ENVIRONMENT_VARIABLE) # 从大字典中取值
    # settings_module = 'day59.settings'
    self._wrapped = Settings(settings_module) # Settings('day59.settings')

    class Settings(object):
      def __init__(self, settings_module): # settings_module = 'day59.settings'
        for setting in dir(global_settings): # 循环获取global_settings文件中所有的名字
          if setting.isupper(): # 在判断名字是否是大写
          # 如果是大写 利用反射 获取到大写的名字所对应的值 不停地添加到对象中
            setattr(self, setting, getattr(global_settings, setting))
            # store the settings module in case someone later cares
            self.SETTINGS_MODULE = settings_module
            mod = importlib.import_module(self.SETTINGS_MODULE) # 'day59.settings'
            # from day59 import settings
            # mod 指代的就是暴露给用户的配置文件模块名

    for setting in dir(mod): # 循环获取暴露给用户配置文件中所有的名字
    if setting.isupper(): # 判断是否是大写
    setting_value = getattr(mod, setting) # 如果是大写 获取大写的变量名所对应的值
    setattr(self, setting, setting_value) # 不停的给对象设置值

    模板传值

    def login(request):
    n = 123
    f = 12.12
    s = '你妹的 真难'
    l = [1,2,3,4,5,6]
    d = {'username':'jason','password':[123,222,444]}
    t = (1,2,3,4,5)
    se = {1,2,3,4}
    b = True
    ctime = datetime.now()
    file_size = 342384234234
    w = '奥术 大师件 大事肯德 基按 实际对 拉 螺栓空当接 龙'
    w1 = 'asdash ashd jkh sadas asdjjs had sjklad j a kjkjdsklas dkjsakldj dlsjakld '
    w2 = 'he llow ord wqe asdsad sadsadsa dsadasds adasds adsadsadsada sdsad'


    def func(xxx):
    print(xxx)
    print('嘿嘿嘿')
    return '你妹的~'

    class MyClass(object):
    @classmethod
    def get_cls(cls):
    return 'cls'

    @staticmethod
    def get_func():
    return 'func'

    def get_self(self):
    return 'self'
    obj = MyClass()


    sss = "<h1>下午上课 一脸懵逼</h1>"
    sss1 = "<script>alert(123)</script>"
    sss2 = "<a href='http://www.xiaohuar.com'>下午上课 需要激情</a>"
    res = mark_safe(sss2) #从后端向前端传前端语句



    xo = '123213213'
    xo1 = 222


    yyy = {'user_list':[1,'22',{'username':['jason','egon']}]}
    return render(request,'login.html',locals())

    #{#模板语法取值#}
    {#<p>{{ n }}</p>#}
    {#<p>{{ f }}</p>#}
    {#<p>{{ s }}</p>#}
    {#<p>{{ l }}</p>#}
    {#<p>{{ d }}</p>#}
    {#<p>{{ se }}</p>#}
    {#<p>{{ t }}</p>#}
    {#<p>{{ b }}</p>#}
    {#<p>如果传递给前端一个函数名 会直接加括号调用 将函数的返回值展示到前端#}
    {# 如果函数有参数 不好意思 django的模板语法 不支持给函数传参#}
    {# {{ func }}#}
    {#</p>#}
    {##}
    {##}
    {#方法都不能传参#}
    {#<p>{{ obj }}</p>#}
    {#<p>{{ obj.get_cls }}</p>#}
    {#<p>{{ obj.get_func }}</p>#}
    {#<p>{{ obj.get_self }}</p>#}

    {#<p>{{ l.1 }}</p>#}
    {#<p>{{ l.3 }}</p>#}
    {##}
    {#<p>{{ d.username }}</p>#}
    {#<p>{{ d.password }}</p>#}
    {#<p>{{ d.password.1 }}</p>#}

    传函数名的时候 会自动加括号调用函数 将函数的返回值展示在html页面上

    注意:
    django模板语法不支持函数传参
    django模板语法在获取容器类型内部元素的值的时候 统一只采用 句点符(.)

    #{#过滤器 #}
    {#特点 会将|左边的当做过滤器的第一个参数 |右边的当前过滤器第二个参数#}
    {#<p>{{ n|add:100 }}</p>#}
    {#<p>{{ n|add:'abc' }}</p>#}
    {#<p>{{ s|add:'sasahhdasda' }}</p>#}
    {#<p>{{ l|length }}</p>#}
    {#<p>{{ d|length }}</p>#}

    {#<p>{{ file_size|filesizeformat }}</p>#}

    {#<p>截取10个字符 三个点也算{{ w1|truncatechars:10 }}</p>#}
    {#<p>截取10个字符 三个点也算{{ w|truncatechars:10 }}</p>#}
    {#<p>安装空格截取单词 三个点不算{{ w1|truncatewords:6 }}</p>#}
    {#<p>安装空格截取单词 三个点不算{{ w|truncatewords:6 }}</p>#}
    {#<p>安装空格截取单词 三个点不算{{ w2|truncatewords:6 }}</p>#}

    {#<p>{{ l|slice:'0:5' }}</p>#}
    {#<p>{{ l|slice:'0:5:2' }}</p>#}

    {#<p>{{ ctime|date:'Y-m-d' }}</p>#}
    {#<p>{{ ctime|date:'Y年/m月' }}</p>#}


    {#<p>{{ sss|safe }}</p>#}
    {#<p>{{ sss1|safe }}</p>#}
    {#<p>{{ res }}</p>#}


    {#<p>{{ xo|default:'' }}#}
    {#有值就拿值 没值就用后面默认的#}
    {#</p>#}

      (前端代码并不一定非要在前端写 你也可以在后端写好 传递给前端页面)
      #前后端取消转义:
      前端
      |safe
      后端
      from django.utils.safestring import mark_safe
      sss2 = "<a href='http://www.xiaohuar.com'>下午上课 需要激情</a>"
      res = mark_safe(sss2)
      
      模板语法的符号就两种:
      {{}} 变量相关
      {%%} 逻辑相关


    #{#标签     if判断  for循环 等等#}
    {#{% if xo %}#}
    {# <p>xo有值</p>#}
    {#{% else %}#}
    {# <p>xo没有值</p>#}
    {#{% endif %}#}

    {#{% if xo %}#}
    {# <p>xo有值</p>#}
    {#{% elif xo1 %}#}
    {# <p>xo1有值</p>#}
    {#{% else %}#}
    {# <p>去他大爷的</p>#}
    {#{% endif %}#}




    #for循环
    内部提供了一个forloop对象
      counter # 1开始
      counter0 # 0开始
      first
      last
      empty 当for循环对象是个空的时候 就会走empty下面的逻辑




    {#{% for foo in l %}#}
    {# {% if forloop.first %}#}
    {# <p>这是我的第一次</p>#}
    {# {% elif forloop.last %}#}
    {# <p>这是最后一次了啊</p>#}
    {# {% else %}#}
    {# <p>嗨起来 大宝贝~</p>#}
    {# {% endif %}#}
    {#{% endfor %}#}


    {#{% for foo in xo %}#}
    {# <p>{{ forloop.counter }}:{{ foo }}</p>#}
    {# {% empty %}#}
    {# <p>你给我的对象是个空的没法进行for循环</p>#}
    {#{% endfor %}#}


    {#{% for foo in d.items %}#}
    {# <p>{{ foo }}</p>#}
    {#{% endfor %}#}
    {##}
    {#{% for foo in d.keys %}#}
    {# <p>{{ foo }}</p>#}
    {#{% endfor %}#}
    {##}
    {#{% for foo in d.values %}#}
    {# <p>{{ foo }}</p>#}
    {#{% endfor %}#}



    {#<p>{{ yyy.user_list.2.username.1 }}</p>#}

    {#{% with yyy.user_list.2.username.1 as dsb %}#} #起别名
    {# <p>{{ dsb }}</p>#}
    {# <p>{{ yyy.user_list.2.username.1 }}</p>#}
    {#{% endwith %}#}





    #自定义过滤器、标签
    {% load my_tag %}
    {#{{ 123|myplus:123 }}#}
    {#只要思想不滑坡 方法总比困难多#}
    {#{{ 123|myplus:'[1,2,3,4,5,6,7,8,]' }}#}

    {#{% load my_tag %}#}
    {% mysm 1 2 3 4 %}


    {% if 0|myplus:123 %}
    <p>有值</p>
    {% endif %}


    {% if mysm 1 2 3 4 %}
    <p>有值</p>
    {% endif %}
     

    步骤:
    1 在应用名下面新建一个templatetags文件夹(必须叫这个名字)
    2 在该文件夹下 新建一个任意名称的py文件
    3 在该py文件内 固定先写两行代码
    from django.template import Library

    register = Library()

    #自定义的过滤器
    @register.filter(name='myplus')
    def index(a,b):
      return a + b

    #自定义的标签
    @register.simple_tag(name='mysm')
      def login(a,b,c,d):
        return '%s/%s/%s/%s'%(a,b,c,d)

    区别: 标签不能再if中使用
      {% if 0|myplus:123 %} 可以用
        <p>有值</p>
      {% endif %}


      {% if mysm 1 2 3 4 %} 不能用
        <p>有值</p>
      {% endif %}




    模板的继承
    #事先需要再模板中 通过block划定区域
    {% block 区域名字 %}

    {% endblock %}

    #子板中使用
    {% extends '模板的名字'%}

    {% block 区域名字 %}
    <h1>登录页面</h1>
    {% endblock %}

    #一个页面上 block块越多 页面的扩展性越高
    通常情况下 都应该有三片区域
    {% block css %}

    {% endblock %}

    {% block content %}

    {% endblock %}

    {% block js %}

    {% endblock %}

    子板中还可以通过
    {{ block.super }} 来继续使用母版的内容




    模板的导入
    当你写了一个特别好看的form表单 你想再多个页面上都使用这个form表单
    你就可以将你写的form表单当作模块的形式导入 导入过来之后 就可以直接展示

    {% include 'good_page.html' %}

     
  • 相关阅读:
    洛谷P1455 搭配购买
    洛谷1341 无序字母对
    打击犯罪
    Cheese
    [noip2002] 产生数
    分治算法-----二分求最大最小
    yl 练习
    cj 练习
    雅礼2018-03-19洛谷作业 2
    雅礼2018-03-19洛谷作业
  • 原文地址:https://www.cnblogs.com/wwei4332/p/11728959.html
Copyright © 2011-2022 走看看