表示関連の操作

1. Djangoのビュー関数ビュー

 ビューと呼ばれるビュー機能(クラス)は、Pythonは、要求を受け取り、ウェブWeb応答を返す単純な関数(クラス)です。

  応答は、ページのHTMLコンテンツ、リダイレクト、404エラー、XMLドキュメント、または絵かもしれません。

2. FBVとCBV

FBV(関数ベースビュー)の閲覧要求の処理機能を使用することです。

CBV(クラスベースビュー)の閲覧要求の処理に使用されます。

クラスの利点

  1. コードの再利用性を改善する、オブジェクト指向技術は、ミックスイン(多重継承)として、使用することができます
  2. コードの可読性を向上させ、決定されていない場合、多くの中で、様々な異なる機能のHTTPメソッド用に処理することができます

2. FBVビュー

例を追加するプレス:関数ベース

url.py

url(r'^publisher_add/', views.publisher_add,name="publisher_add")

views.py

def publisher_add(request):        # 基于函数
    error = ""                     # GET时为空
    if request.method == "POST":
        # 获取用户提交的出版社的信息
        pub_name = request.POST.get("name")
        pub_addr = request.POST.get("addr")
        # 对用户提交的数据进行校验
        if not pub_name:
            # 为空时
            error = "不能为空"

        elif models.Publisher.objects.filter(name=pub_name):
            # 重名时
            error = "出版社名字已存在"

        else:
            models.Publisher.objects.create(
                name=pub_name,
                addr=pub_addr,
            )
            return redirect("publisher_list")
    # 为get请求时就返回页面,error值为空
    return render(request, "publisher/publisher_add.html", {"error":error})

3. CBVビュー

url.py

# PublishAdd是类,要执行as_view()方法
url(r'^publisher_add/', views.PublishAdd.as_view(),name="publisher_add"),

views.py

from django.views import View
class PublishAdd(View):

    def get(self,request):        # 源码有8中请求方法
        # print(1,request.method)
        return render(request, "publisher/publisher_add.html")

    def post(self,request):
        # print(2,request.method)
        # 获取用户提交的出版社的信息
        pub_name = request.POST.get("name")
        pub_addr = request.POST.get("addr")
        # 对用户提交的数据进行校验
        if not pub_name:
            # 为空时
            error = "不能为空"

        elif models.Publisher.objects.filter(name=pub_name):
            # 重名时
            error = "出版社名字已存在"

        else:
            models.Publisher.objects.create(
                name=pub_name,
                addr=pub_addr,
            )
            return redirect("publisher_list")
    # 为get请求时就返回页面,error值为空
        return render(request, "publisher/publisher_add.html", {"error":error})

4. CBV演算処理(ソース)

  1. ロードされたとき、実行urls.pyのas_view()メソッドは、現在のクラスはビュー機能を返す、親が行われていません。

  2. 要求は、ビュー機能を実行しています:

    1. 「自己 - クラスをインスタンス化

    2. self.request =要求

    3. 执行self.dispatch(要求、* argsを、** kwargsから)

      1. 要求が許可されるかどうかの方法を決定します:

        1. 許します

          反射して、現在のモードに対応する要求オブジェクトを取得する方法

          ハンドラ= GETATTR(自己、request.method.lower()、self.http_method_not_allowed)

        2. 許可されていません

          ハンドラ= self.http_method_not_allowed

          1. 実行ハンドラは結果を得るために、最終的にはジャンゴに戻りました

ソースを表示カテゴリ:

class View(object):

    http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

    def __init__(self, **kwargs):

        for key, value in six.iteritems(kwargs):
            setattr(self, key, value)

    @classonlymethod  # 类方法
    def as_view(cls, **initkwargs):   # 第一执行此方法,cls是PublishAdd类
        """
        Main entry point for a request-response process.
        """
        for key in initkwargs: 
            if key in cls.http_method_names:
                raise TypeError("You tried to pass in the %s method name as a "
                                "keyword argument to %s(). Don't do that."
                                % (key, cls.__name__))
            if not hasattr(cls, key):
                raise TypeError("%s() received an invalid keyword %r. as_view "
                                "only accepts arguments that are already "
                                "attributes of the class." % (cls.__name__, key))

        def view(request, *args, **kwargs):  # 执行view函数
            self = cls(**initkwargs)  # 实例化一个当前类对象,cls指的是当前类名.加()实例化对象
            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) # 重点:执行调遣函数,确认是执行哪一个方法.
        view.view_class = cls
        view.view_initkwargs = initkwargs

        # take name and docstring from class
        update_wrapper(view, cls, updated=())

        # and possible attributes set by decorators
        # like csrf_exempt from dispatch
        update_wrapper(view, cls.dispatch, assigned=())
        return view   # 返回一个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.
        if request.method.lower() in self.http_method_names: # 判断请求是否被允许
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)

    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())

3.ビューデコレータに追加

1.定義:

クロージャ:クロージャは、ネストされた関数の内機能層(非グローバル変数)外部参照変数の関数です。

裁判官:関数名.__コード__ co_freevarsは自由変数の関数を表示します

アクション閉鎖:データのセキュリティを確保するために、地元の情報が破壊されていない保存

デコレータ:基本的に閉鎖、オープンの閉鎖原則

1.拡張子が開いています

我々はすでに、すべての機能を有しており、任意の将来のアップデートや修正せずに任意のプログラムは、それが設計の初めには不可能である、と言います。だから我々は、新しい機能を追加し、コード拡張を許可する必要があります。

2.変更を閉じています

我々が使用することを他の人に配信されている可能性がある関数を記述し、我々は内部関数を変更したり、機能を変更し、この時間が呼び出された場合、既に他に影響を与える可能性があるため、私たちは、前述のようにユーザーが機能を使用しています。

だから、完璧な最終的な定義があるデコレータ:機能を元のソースに装飾するコードと呼び出しを変更することなく、追加の機能を追加します。

2.デコレータのアップグレード版

import functools
def wrapper(f):

    @functools.wraps(f)       # 使得打印结果与被装饰的函数相同,而非inner
    def inner(*args,**kwargs):
        """
        这是一个inner函数
        :param args:
        :param kwargs:
        :return:
        """
        # 装饰前
        return f(*args,**kwargs)
        # 装饰后
    return inner
                                                    # f = index
@wrapper                        index = wrapper(index) # index = inner
def index(a1,a2):               index()  # inner()
    """
    这是一个index函数
    :param a1:
    :param a2:
    :return:
    """
    return a1 + a2

print(index.__name__)   #获取函数名
print(index.__doc__)    #获取注释

FBVを追加する3.デコレータ

### 计时装饰器
import time
def timmer(func):
    def inner(*args, **kwargs):
        start_time = time.time()
        ret = func(*args, **kwargs)
        print(f'当前函数运行时间:{time.time() - start_time}')
        return ret
    return inner

@timmer
def publisher_add(request):        # 基于函数
    error = ""                     # GET时为空
    if request.method == "POST":
        # 获取用户提交的出版社的信息
        pub_name = request.POST.get("name")
        pub_addr = request.POST.get("addr")
        # 对用户提交的数据进行校验
        if not pub_name:
            # 为空时
            error = "不能为空"

        elif models.Publisher.objects.filter(name=pub_name):
            # 重名时
            error = "出版社名字已存在"

        else:
            models.Publisher.objects.create(
                name=pub_name,
                addr=pub_addr,
            )
            return redirect("publisher_list")
    # 为get请求时就返回页面,error值为空
    return render(request, "publisher/publisher_add.html", {"error":error})

CBVを追加する4.デコレータ

django.utils.decorators輸入method_decoratorから

1の方法に適用されます

@method_decorator(timmer)
def get(self,request):    # 哪个方法需要就加在哪个方法上

前記方法は、ディスパッチに適用しました

    @method_decorator(timmer)
    def dispatch(self, request, *args, **kwargs):  # 重构父类再添加
        ret = super().dispatch(request, *args, **kwargs)
        return ret

@method_decorator(timmer, name='dispatch')    # 加在父类的dispatch方法上
class PublisherAdd(View):

第3の方法

@method_decorator(timmer, name='post')
@method_decorator(timmer, name='get')
class PublisherAdd(View):    # 直接加在类上面

4.具体的な例

### 计时装饰器
import time
def timmer(func):
    def inner(*args, **kwargs):
        start_time = time.time()
        ret = func(*args, **kwargs)
        print(f'当前函数运行时间:{time.time() - start_time}')
        return ret
    return inner

from django.views import View
from django.utils.decorators import method_decorator
# 此处加装饰器
class Publisher_add(View):
    # 此处加装饰器
    #重构父类,父类有此方法(源码,必须继承父类,还有其他方法)
    def dispatch(self, request, *args, **kwargs):
        print("请求来了")
        #接收到父类返回值
        ret = super(PublishAdd, self).dispatch(request, *args, **kwargs)
        print("逻辑处理结束了")
        print(ret)
        #必须return,继承父类有返回值,返回方法的返回值
        return ret
    # 此处加装饰器
    def get(self,request):
        print(1,request.method)
        return render(request, "publisher/publisher_add.html")
    # 此处加装饰器
    def post(self,request):
        print(2,request.method)
        # 获取用户提交的出版社的信息
        pub_name = request.POST.get("name")
        pub_addr = request.POST.get("addr")
        # 对用户提交的数据进行校验
        if not pub_name:
            # 为空时
            error = "不能为空"

        elif models.Publisher.objects.filter(name=pub_name):
            # 重名时
            error = "出版社名字已存在"

        else:
            models.Publisher.objects.create(
                name=pub_name,
                addr=pub_addr,
            )
            return redirect("publisher_list")
    # 为get请求时就返回页面,error值为空
        return render(request, "publisher/publisher_add.html", {"error":error})

4.要求の要求 - プロパティとメソッド

1.リクエストオブジェクト

ページが要求された場合、Djangoはこの要求ののHttpRequestオブジェクトは、元の情報が含まれて作成されます。
ジャンゴこのオブジェクトは、自動的にオブジェクトのリクエストパラメータを受信規約を使用してビュー応答関数、一般的なビュー関数に渡されます。

公式ドキュメント

2.リクエスト関連のプロパティ

ret2 = request.method       # 获得请求方式
ret3 = request.GET          # GET请求方式,url上携带的参数 /?a=1&b=2
ret4 = request.POST         # POST请求方式,post请求提交的参数 enctype="application/x-www-form-urlencoded" form中的一个属性,注意上传文件区别
ret6 = request.body          # 请求体的信息,get为b"",post 才有提交的数据
ret7 = request.COOKIES       # cookie信息
ret8 = request.session       # session信息
ret9 = request.FILES         # 获得上传文件信息
ret10 = request.META         # 获得所有的头信息  bejson解析 字典,[键]取值
ret = request.path           # 路径信息 (不包含IP和端口 也不包含查询参数)
ret5 = request.path_info     # 路径信息 (不包含IP和端口 也不包含查询参数) 

関連の要求の3方法

ret1 = request.get_full_path()  # 路径信息  不包含IP和端口 包含查询参数
ret2 = request.is_secure()  # 如果请求时是安全的,则返回True;即请求通是过 HTTPS 发起的
ret3 = request.is_ajax()    # 是否是ajax请求 布尔值
ret4 = request.POST.getlist("hobby")  # 有多个值,get是一个,多表操作

ファイルをアップロードする5.フォームフォーム

upload.htmlファイル

    <h1>文件上传</h1>
    <form action="" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        用户名:<input type="text" name="username">
        密码:<input type="password" name="password">
        头像:<input type="file" name="file" multiple>
        <input type="submit">
    </form>

views.pyファイル

from django.conf import settings
#全局配置,一般不用自己的settings
def upload(request):
    if request.method == "GET":
        return render(request,"upload.html")
    else:
        print(request.POST)       #得到post请求数据,queryset对象
        print(request.FILES)      #得到文件对象数据
        user = request.POST.get("username")
        pwd = request.POST.get("password")
        file_obj = request.FILES.get("file")
        # print(file_obj.name)
        with open(file_obj.name,"wb") as f:
            # for i in file_obj:   第一种接收方法
            #    f.write(i)
            for chunk in file_obj.chunks():  第二种接收方法
                f.write(chunk)

        return HttpResponse("ok")

前記コーディングタイプにenctype =「multipart / form-データは 」、 セグメント受信機/ N / rは、多くの時間データメモリが爆発受け取ることはありませんアップロードファイル転送セグメントは、あなたは、このプロパティを追加しなければならないこと。複数のオブジェクトを示す複数の属性は、アップロード、及びチャンクがあるの()メソッドは、デフォルトのサイズが2.5Mまで、即ち64キロバイト、65536Bとして試験されたグローバル設定ファイルを変更する変更時ジェネレータであり、返さ

6.レスポンスレスポンス

これらは、4つの基本的返すHttpResponseオブジェクトのソースコードを見るために、具体的に、オブジェクトを

# HttpResponse 返回字符串
# render 返回一个页面   ,基于HttpResponse
# redirect 重定向      ,基于HttpResponse,响应头 Location: 地址
# JsonResponse  返回json格式的数据 ,基于HttpResponse

from django.http import JsonResponse # 导入模块

def json_response(request):
    data={'name':'abc','age':18}  # 字典类型的数据,默认支持
    data2=['1','2','3']           # 默认不支持列表或其他类型的数据.需要设置一个条件,safe=False
                                # 如:JsonResponse(data2,safe=False)
    return  JsonResponse(data)

一時的および恒久的なリダイレクトリダイレクト

return redirect(object, permanent=True)  # 注意参数
临时重定向(响应状态码:302)和永久重定向(响应状态码:301)对普通用户来说是没什么区别的,它主要面向的是搜索引擎的机器人。
A页面临时重定向到B页面,那搜索引擎收录的就是A页面。
A页面永久重定向到B页面,那搜索引擎收录的就是B页面。

おすすめ

転載: www.cnblogs.com/lvweihe/p/11767315.html