Django 类视图(class base view)关于http请求的处理过程

按Django官方的说法,在Django开发过程中我们可以使用function-base-view(函数视图)和clase-base-view(类视图)实现http请求的相关处理。函数视图和类视图没有优劣的区分,各有好处。

函数视图处理http请求的时可以直接调用request.method属性进行判断http请求的类型,如:

from django.http import HttpResponse

def my_view(request):
    if request.method == 'GET':
        # <view logic>
        return HttpResponse('result')

使用类视图时实现http请求处理时可以将每种请求写成类的方法,便于扩展,如对继承自基本类View,编写get()方法,当HTTP发起get()请求时会自动匹配到这个自定义的get()方法。

from django.http import HttpResponse
from django.views import View

class MyView(View):
    def get(self, request):
        # <view logic>
        return HttpResponse('result')

首先在view.generic.base.py中可以找到所有已定义的http请求类型:

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

当HTTP发起请求时,通过类视图的as_view()方法传入请求类型,as_view()就根据上面定义的方法进行遍历找到。具体地在as_view(),又分别调用setup()dispatch()方法,其中dispatch()方法就是通过python类的内置函数getattr()方法查找当前扩展类中是否有类方法与HTTP请求匹配,如上面例子中的get()处理方法。当查找到相应的方法后as_view()就会返回这个自定义方法的结果:

        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            if hasattr(self, 'get') and not hasattr(self, 'head'):
                self.head = self.get
            self.setup(request, *args, **kwargs)
            if not hasattr(self, 'request'):
                raise AttributeError(
                    "%s instance has no 'request' attribute. Did you override "
                    "setup() and forget to call super()?" % cls.__name__
                )
            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=())

    def setup(self, request, *args, **kwargs):
        """Initialize attributes shared by all view methods."""
        self.request = request
        self.args = args
        self.kwargs = kwargs

    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)

这样在Django开发过程中,当使用到类视图如View, ListView, DetailView, TemplateView时可以通过编写类方法的方式自定义get, post等请求的处理,在后续开发中可以灵活地重写这些方法,以达到需求。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当使用Django视图时,可以通过继承来实现代码的复用和逻辑的扩展。以下是一个示例,展示了如何使用视图继承。 假设我们有两个视图:一个用于显示所有文章,另一个用于显示单个文章的详细信息。我们可以定义一个基础视图来包含共享的逻辑,并让其他视图继承它。 ```python from django.views import View from django.shortcuts import render from .models import Article class BaseArticleView(View): template_name = 'articles/base_article.html' def get_queryset(self): return Article.objects.all() def get_context_data(self, **kwargs): context = { 'articles': self.get_queryset() } context.update(kwargs) return context def get(self, request, *args, **kwargs): context = self.get_context_data() return render(request, self.template_name, context) class AllArticlesView(BaseArticleView): template_name = 'articles/all_articles.html' class SingleArticleView(BaseArticleView): template_name = 'articles/single_article.html' def get_queryset(self): article_id = self.kwargs.get('article_id') return Article.objects.filter(id=article_id) ``` 在上述示例中,我们定义了一个基础视图`BaseArticleView`,它包含了获取所有文章、生成上下文数据和渲染模板的通用逻辑。然后,我们创建了两个子视图`AllArticlesView`和`SingleArticleView`,它们分别继承了基础视图。 `AllArticlesView`继承了`BaseArticleView`,并覆盖了`template_name`属性,以便使用特定的模板来显示所有文章。 `SingleArticleView`也继承了`BaseArticleView`,并覆盖了`template_name`和`get_queryset()`方法,以便使用不同的模板来显示单个文章,并根据URL中的参数过滤查询集。 通过这种方式,我们可以在基础视图中处理通用的逻辑,并在子视图中实现特定的需求和定制化。这样可以避免重复编写相似的代码,提高代码复用性和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值