ビュー層とテンプレート層04のジャンゴ

ルート:ビュー機能メモリアドレス

ビューレイヤー

テンプレートとレンダリング方法は、コンテックス使用される二つのオブジェクトの組合せであります

from django .template import Template,Context
def func1(request):
    res = Template('<h1>{{user}}</h>')
    con=Context({'user':{'username':'zhang','password':123,}})
    return HttpResponse(res.render(con))

JsonResponseオブジェクト

JsonResponseは、JSONエンコードされたレスポンスを生成するように設計された、のHttpResponseのサブクラスです。

# ensure_ascii=False 默认等于True,设置成False,遇到中文不再进行转码,仅仅只是进行序列化,转换成json形式的字符串
import json
def func(request):
    d={'a':1,'b':3,'c':3,'d':4,'e':'速度发货!!!!!!!'}
    return HttpResponse(json.dumps(d,ensure_ascii=False),)  # 
from django.http import JsonResponse
def func(request):
    d={'a':1,'b':3,'c':3,'d':4,'e':'速度发货!!!!!!!'}
    l=[1,2,3,4,5,]
   # return JsonResponse(d)  # 加括号是个对象,内部也是基于json.dumps进行的序列化,默认遇到中文也会转成ASCII编码,
    # return JsonResponse(d,json_dumps_params={'ensure_ascii':False})  # 遇到中文不转码
    return JsonResponse(l,safe=False)  # In order to allow non-dict objects to be serialized set the safe parameter to False.  根据报错信息,去源码找到JsonResponse不能序列化其他数据类型的原因,就是修改safe=True 为False,之后就能序列化其他数据类型(json模块能序列化的)了

CBVとソースコード解析

私たちは、FBVと呼ばれるビュー機能に基づいており、前に書きました。ビューには、クラスベースのように記述することができます。
FBV:ビュー関数に基づいて
CBV:ビュークラスベース

from django.views import View

class MyLogin(View):
    def get(self,request):
        print('我是MyLogin里面的get方法')
        return render(request,'login.html')

    def post(self,request):
        print('我是MyLogin里面的post方法')
        return HttpResponse('post')

    # 路由的书写 与CBV有点不同
    # FBV写法     路由 >>> 视图函数内存地址
    url(r'^index/',views.index),
    # CBV写法
    url(r'^login/',views.MyLogin.as_view())  # views.view  本质也是FBV
     http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
    
     def http_method_not_allowed(self, request, *args, **kwargs):
        logger.warning(
            'Method Not Allowed (%s): %s', request.method, request.path,
            extra={'status_code': 405, 'request': request}
        )
        return http.HttpResponseNotAllowed(self._allowed_methods())
    
    @classonlymethod
    def as_view(cls, **initkwargs):
        def view(request, *args, **kwargs):  # 闭包函数
            self = cls(**initkwargs)  # cls是我们自己写的类 MyLogin  self是我们自己定义的类的对象
            # 在看源码的时候 你一定要把握住一个顺序 对象在查找属性和方法的时候
            # 先从对象自身找 再去产生对象的类中找 再去类的父类中找
            return self.dispatch(request, *args, **kwargs)
        return view


    def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesn't exist,
        # defer to the error handler. Also defer to the error handler if the
        # request method isn't on the approved list.
        # 判断当前请求方式在不在默认的八个方法内
        # 1.先以GET请求为例
        if request.method.lower() in self.http_method_names:
            # 利用反射去我们自己定义类的对象中查找get属性或者是方法  getattr(obj,'get')
            # handler = get方法
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
                return handler(request, *args, **kwargs)  # 调用get方法

CBVプラスデコレータ方法

デコレータ装飾FBV
FBVは、関数自体であり、従って通常の機能に追加差はデコレータません。

def wrapper(func):
    def inner(*args, **kwargs):
        start_time = time.time()
        ret = func(*args, **kwargs)
        end_time = time.time()
        print("used:", end_time-start_time)
        return ret
    return inner


# FBV版添加班级
@wrapper
def add_class(request):
    if request.method == "POST":
        class_name = request.POST.get("class_name")
        models.Classes.objects.create(name=class_name)
        return redirect("/class_list/")
    return render(request, "add_class.html")

CBVプラスデコレータ方法

独立した機能が同一でないメソッドのクラスは、メソッドを直接デコレータクラスの関数に適用することができない、我々は、メソッドのデコレータへの最初の変換、それが必要です。

Djangoは方法デコレータデコレータに変換するmethod_decorator装飾的な機能を提供します

#使用CBVに注意を払う必要があり、要求は最初の行いが(派遣来た)この方法は、そのようなので、GET、POST、およびなどの特定の要求の処理方法の必要量は、我々は手動で発送方法を書き換えることができ、運用時間、いくつかの、派遣を行う場合同じ効果を高め、FBVでデコレータする方法。

给CBV加装饰器 推荐你使用内置模块
from django.utils.decorators import method_decorator

# 2.可以指定给谁装
# @method_decorator(wrapper,name='post')  # name=... 表示指定给谁装
# @method_decorator(wrapper,name='dispatch')
class MyLogin(View):
    @method_decorator(wrapper)
    def dispatch(self, request, *args, **kwargs):  # 如果你想在视图函数执行之前 做一些操作 你可以在你的CBV中定义dispatch方法来拦截

        return super().dispatch(request,*args,**kwargs)
    # @outter  # 1.直接写
    # @method_decorator(outter)  # 1.推荐写法
    def get(self,request):
        print('我是MyLogin里面的get方法')
        return render(request,'login.html')
    # @outter
    def post(self,request):
        print('我是MyLogin里面的post方法')
        time.sleep(1)
        return HttpResponse('post')

テンプレート層

値によってテンプレートの構文

テンプレートの構文

2つだけの形式を書き込む:
{} {}関連する変数
関連する論理は、{} %%

値によってテンプレート:pythonの値がサポートしているすべての基本データ型を

変数

{{名前}}変数:で使用Djangoテンプレート言語の構文をクリックします。

テンプレートエンジンが変数に遭遇すると、変数を計算し、その結果自分自身でそれを置き換えます。名前付き変数は任意の英数字とアンダースコア(「_」)の組み合わせが含まれます。変数名にはスペースや句読点を含めることはできません。

ドット(。)テンプレート言語で特別な意味を持っています。テンプレートシステムはドット(「」)に遭遇すると、それはこの順序の問い合わせになります。

辞書引き(辞書引き)
プロパティやメソッドクエリ(属性やメソッド・ルックアップ)
デジタルインデックスクエリ(数値索引参照)

注意事項:

  1. 計算結果の値が呼び出された場合は、パラメータなしで呼び出されます。呼び出しの結果は、テンプレートの値になります。
  2. 変数が存在しない場合、システムはデフォルトの設定は「あるある値string_if_invalidテンプレートオプション、」(空の文字列)を挿入します
# test.py文件
def test(request):
    n=1
    f=1.11
    s='hello baby~'
    l=[1,2,3,4,]
    t=(1,2,3,44,55)
    d={'name':'zhangsan','hobby':'read'}
    se={12,13,14,15,}
    b=False
    def index1():  #给HTML页面传递函数名的时候 模板语法会自动加括号调用该函数 并且将函数的返回值当做展示依据,模板语法不支持函数传参 也就意味着 你传给html页面的只能是不需要传参调用的函数
        return '都是废话'
    class Test(object):
        def get_self(self):
            return 'get_self'
    obj = Test()
    return render(request,'test.html',locals())

# 传类名像函数名一样,也是加括号调用,实例化一个对象;传对象,就是对象本身,是类的对象的内存地址;只要是能够加括号调用的 传递到html页面上都会自动加括号调用
<!--test.html文件-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link rel="stylesheet" href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>

</head>
<body>
<p>{{ n }}</p>
<p>{{ f }}</p>
<p>{{ s }}</p>
<p>{{ l }}</p>
<p>{{ se }}</p>
<p>{{ d }}</p>
<p>{{ b }}</p>
<p>传函数名:{{ index1 }}</p>
<p>传函数名:{{ Test }}</p>   
<p>传函数名:{{ obj }}</p>  
</body>
</html>

フィルター(フィルター)

テンプレートの構文もあなたにいくつかのビルトインすばやくデータを処理するのに役立つ方法与える
:フィルタの構文を {| FILTER_NAME {値:パラメータを}}

例えば:{{名前|低い}}次に、変数名は、下部フィルタを適用した後、その値が表示されます。ここでは、アクションに下げることはすべて小文字のテキストです。

注意事項:

1.フィルタサポート「チェーン」操作。即ち、別のフィルタへの入力としてフィルタ出力。
2.フィルタは、例えば、パラメータを受け入れることができる:{{SSS | truncatewords:30 }}、 SSSの最初の30ワードが表示されています。
3.フィルタパラメータは、引用符で囲む必要があり、スペースが含まれています。{|参加{リスト:「」}}カンマとスペースのような、リストの要素を接続するために使用されるような
4 『|』はスペースにはスペースを残さないにスペースはありません

フロントとリアエンドアンエスケープ
フロント
|安全な
バックエンド
のインポートmark_safe django.utils.safestringから
SSS2を= "

マイH2タグ


RES = mark_safe(SSS2)

<p>统计长度(如果无法统计默认返回0):{{ s|length }}</p>
<p>加法运算(内部异常捕获 支持数字相加 字符串拼接 都不符合返回空):{{ n|add:f }}</p>
<p>切片操作 顾头不顾尾 也支持步长:{{ l|slice:'0:5:2' }}</p>
<p>判断是否有值(有值展示值本身 没值展示默认值):{{ is_value|default:'is_value变量名指向的值为空' }}</p>
<p>自动转成文件大小格式:{{ file_size|filesizeformat }}</p>
<p>截取文本内容(字符) 截取五个字符 三个点也算:{{ s|truncatechars:8 }}</p>
<p>截取文本内容(按照空格计算) 截取五个字符 三个点不算 :{{ s1|truncatewords:5 }}</p>
<p>默认情况下,不会转换成前端html标签 :{{sss}}</p>  # 后端传来的字符串类型的标签
<p>展示带有标签的文本:{{ sss|safe }}</p> 添加safe参数之后可以转换后端传来的字符串标签
<p>展示带有标签的文本:{{ ss|safe }}</p>  后端: ss='<script>alert(123)</script>'

タグ

関連タグロジック
IF
ループのために

{% for foo in l %}
    {{ forloop }}
    {% if forloop.first %}
        <p>{{ foo }}</p>
​   {% elif forloop.last %}
​   {% else %}
        <p>{{ foo }}</p>
​   {% endif %}
​   {% empty %}
        <p>档for循环的对象为空的时候走这个!</p>
{% endfor %}

テンプレートの構文の値はピリオド文字を統一する唯一の方法を使用しています(。)

<p>{{ comp_dic.hobby.2.2.age }}</p>
<p>当你的数据是通过比较复杂的点点点获取到的后续又需要经常使用 你可以给该数据起别名 别名只能在with内部使用</p>
{% with comp_dic.hobby.2.2.age as age  %}    
    <p>{{ age }}</p>
    <p>{{ comp_dic.hobby.2.2.age }}</p>
{% endwith %}

カスタムフィルタとラベル

カスタムフィルタ

Djangoは、ユーザー定義のサポート
最初の3の準備ができている必要があり
、新しい名前の名前で1.アプリケーションでは、フォルダtemplatetagsを呼び出さなければなりません
フォルダPYファイルに任意の名前を作成します。2.
PYファイルに記述する必要があります3。以下の2つのコード
django.templateインポートライブラリから
レジスタ=ライブラリ()

その後は、レジスタカスタマイズフィルタやラベルを使用することができます

# 应用名下templatetag文件夹 mytag.py文件
from django.template import Library
register = Library()
# 自定义过滤器,跟默认的过滤器一样,最多只能接受两个参数
@register.filter(name='xxx') # 给过滤器起名字
def index(a,b):
    return a+b

使用カスタムフィルタは、HTMLページにロードする必要があります。

<!--test.html文件-->
{% load mytag %}
{{ 1|xxx:99 }}

カスタムラベル

# 应用名下templatetag文件夹 mytag.py文件

# 自定义标签   可以接受任意多个参数
@register.simple_tag(name='zzz')
def mytag(a,b,c,d):
    return '%s?%s?%s?%s'%(a,b,c,d)
<!--test.html文件-->
{% load mytag %}
{% zzz 'a' 'b' 'c' 'd' %}
<!--test.html文件-->
<p>自定义的过滤器可以在逻辑语句使用 而自定义的标签不可以</p>
{% if 1|xxx:99 %}
    <p>有值</p>
{% else %}
    <p>无值</p>
{% endif %}

カスタムinclusion_tag

外の世界の機能は、HTMLページに渡され、その後、着信パラメータを受け入れる、とすることができますされ、レンダリングされたデータを取得した後、inclusion_tagページを呼び出すために良い場所にページをレンダリングします

# 应用名下templatetag文件夹 mytag.py文件
# 自定义inclusion_tag
@register.inclusion_tag('mytag.html',name='xxx')
def index666(n):
    l = []
    for i in range(n):
        l.append('第%s项'%i)
    return locals()  # 将l直接传递给mytag.html页面
<!--mytag.html文件-->
<!--只做临时渲染的页面,所以该页面的其他框架部分html代码就不需要了-->
<ul>
    {% for foo in l %}
        <li>{{ foo }}</li>
    {% endfor %}
</ul>
<!--test.html文件-->
<p>自定义inclusion_tag的使用  当你需要使用一些页面组件的时候 并且该页面组件需要参数才能够正常渲染 你可以考虑使用inclusion_tag</p>
{% load mytag %}
{% xxx 5 %}

継承されたテンプレート

あなたが任意の領域を指定しない場合、その後、あなたがページを変更することはできませんどの手段、その後、連続して、あなたが指定した領域を使用することができ、使用することをページ上で事前に定義された領域に必要コンテンツ。

<!--先在页面上利用block划定你以后可能想改的区域-->
{% block content %}
{% endblock %}

<!--继承之后  就可以通过名字找到对应的区域进行修改-->
{% extends 'home.html' %}

{% block content %}
<!--修改模板中content区域内容-->
{% endblock %}
            
模板上的block区域越多 页面的扩展性越强
建议你一个模板页面至少有三块区域:
    css区域
    html代码区域  可以设置多个block
    js区域
有了这三块区域 就能够实现每一个页面都有自己独立的css和js代码

{% extends 'home.html' %}  子文件就可以通过这个方法继承猪文件的html代码的格式
{% block css %}
<style>
    p {
        color: green;
    }
</style>
{% endblock %}

{% block content %}
<p>login页面</p>
{% endblock %}

{% block js %}
<script>
    alert('login')
</script>
{% endblock %}

你还可以在子页面上继续沿用父页面的内容
        {{ block.super }}

テンプレート継承されます
あなたはあなたが未来を変更することができますブロック画定エリアを継承させたい最初のページ1.
最初のサブ継承がページ上の拡張2.
3.ブロック自動的にコンテンツを変更したいエリアを選択するように求め

テンプレートのインポート

モジュールとしてHTMLページを直接使用して導入された
{%「をbform.html」%含みます}

おすすめ

転載: www.cnblogs.com/zhangchaocoming/p/11939438.html