• Django创建通用视图函数


    想在我们有两个视图:

    def thinkingview(request):
        user = request.user
        if request.method == 'GET':
            return render(request, 'think.html', {'user': user})
        elif request.method == 'POST:
            user = request.user
            data_form = ThinkingForm(request.POST)
            if data_form.is_valid():
                data_form.save()
                return redirect('index')
            else:
                return render(request, 'think.html', {'user': user, 'error': data_form.errors})
    def questionview(request):
        user = request.user
        if request.method == 'GET':
            user = request.user
            return render(request, 'question.html', {'user': user})
        elif request.method == 'POST:
            data_form = QuestionForm(request.POST)
            if data_form.is_valid():
                data_form.save()
                return redirect('index')
            else:
                return render(request, 'question.html', {'user': user, 'error': data_form.errors})

    这两个视图非常相似,GET渲染页面并预置用户信息,POST提交文本数据,不同的只有tamplate和form这两个对象。现在把这两个对象抽象出来,创建一个通用的视图:

    # view.py
    def reportview(request, tamplate_name, form):
        user = request.user
        if request.method == 'GET':
            user = request.user
            return render(request, tamplate_name, {'user': user})
        elif request.method == 'POST:
            data_form = form(request.POST)
            if data_form.is_valid():
                data_form.save()
                return redirect('index')
            else:
                return render(request, tamplate_name, {'user': user, 'error': data_form.errors})

    通过URLconf的传递额外参数的方式来传递这两个对象:

    # urls.py
    from django.conf.urls import url
    from myapp import forms, views
    
    urlpatterns = [
        url(r'^thinking/$', views.report, {'tamplate_name': 'thinking.html', 'form': forms.ThinkingForm}),
        url(r'^question/$', view.report, {'tamplata_name': 'question.html', 'form': forms.QuestionForm})

    这样就有了一个可复用的、与对象无关的视图(在URLconf中甚至可以传递model)!如果再有类似功能的视图时就可以重用这个report视图,而不需要再写视图代码。

    现在来做一些优化,在同一个视图函数中对POST 和GET 进行处理是一种比较粗糙的做法,一个比较好的设计习惯应该是,用两个分开的视图函数——一个处理POST请求,另一个处理GET请求,然后在相应的地方分别进行调用。
    写一个分发函数,由它来分派GET和POST请求:

    #views.py
    from django.views.decorators.http import require_http_methods
    ...
    
    
    def method_splitter(request, *args, **kwargs):
        #对http method进行分发
        get_view = kwargs.pop('get', None)
        post_view = kwargs.pop('post', None)
        if request.method == 'GET' and get_view is not None:
            return get_view(request, *args, **kwargs)
        elif request.method == 'POST' and post_view is not None:
            return post_view(request, *args, **kwargs)
        raise Http404
    
    @require_http_methods('GET')
    def report_get(request, tamplate_name):
        user = request.user
        return render(request, tamplate_name, {'user': user})
    
    @require_http_methods('POST')
    def report_post(request, tamplate_name, form):
        data_form = form(request.POST)
        if data_form.is_valid():
            data_form.save()
            return redirect('index')
        else:
            return render(request, tamplate_name,  'user': request.user, 'error': data_form.errors})
    
    
    #urls.py
    urlpatterns = [
        url(r'^thinking/$', views.report, {'tamplate_name': 'thinking.html', 'form': forms.ThinkingForm, 'get': view.report_get, 'post': view.report_post}),
        url(r'^question/$', view.report, {'tamplata_name': 'question.html', 'form': forms.QuestionForm, 'get': view.report_get, 'post': view.report_post})

    现在我们就拥有了一个不错的,可以通用的视图函数了,里边封装着由request.method 的返回值来分派不同的视图的程序.

  • 相关阅读:
    linux网桥浅析
    linux slub分配器浅析
    vs2015 C# WinForm 使用皮肤 美化窗体
    枚举可以直接赋值给int
    LINK : fatal error LNK1000: Internal error during IncrBuildImage
    map映射类
    map
    time
    int to string
    eclipse
  • 原文地址:https://www.cnblogs.com/thunderLL/p/7372060.html
Copyright © 2020-2023  润新知