Django基础教程(109)Django基于类的视图之使用类视图重写API:告别祖传代码!Django类视图让你写API像点菜一样简单

记得我刚学Django那会儿,看着教程里的函数视图觉得这玩意儿真简单。一个函数处理一个请求,if request.method == ‘GET’ 就返回数据,if request.method == 'POST' 就保存数据,清晰直白得像一碗蛋炒饭。

直到我的项目变成了“祖传代码”......

那个处理用户管理的views.py文件,已经从最初的50行膨胀到了500行。各种if-else嵌套得像俄罗斯套娃,验证逻辑和业务逻辑纠缠得比耳机线还乱。每次新增功能我都得小心翼翼,生怕碰坏了哪个角落里沉睡的bug。

就在我准备给这个文件办个“500行庆典”的时候,同事老王瞥了一眼我的屏幕,轻飘飘地来了句:“你还在用函数视图啊?类视图它不香吗?”

一、为什么要从函数视图升级到类视图?

1. 告别“if-else地狱”

函数视图处理多个HTTP方法时,通常长这样:

def article_list(request):
    if request.method == 'GET':
        # 获取文章列表
        articles = Article.objects.all()
        return JsonResponse({'articles': list(articles.values())})
    
    elif request.method == 'POST':
        # 创建新文章
        data = json.loads(request.body)
        article = Article.objects.create(**data)
        return JsonResponse({'id': article.id}, status=201)
    
    else:
        return JsonResponse({'error': '方法不允许'}, status=405)

看起来还行?等你要支持PATCH、DELETE、PUT的时候,这个函数就会胖到亲妈都不认识。

而类视图把这些方法拆解成了独立的函数,每个函数专注做一件事:

class ArticleView(View):
    def get(self, request):
        # 只处理GET请求
        pass
    
    def post(self, request):
        # 只处理POST请求
        pass

这不就是Python界著名的“单一职责原则”吗?

2. 继承的力量,拒绝重复造轮子

假设你有10个API都需要用户登录才能访问。在函数视图里,你要么写10个@login_required装饰器,要么自己写个装饰器。

但在类视图里,你可以:

class LoginRequiredView(View):
    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return JsonResponse({'error': '请先登录'}, status=401)
        return super().dispatch(request, *args, **kwargs)

class ArticleView(LoginRequiredView):
    # 这个类自动拥有了登录检查功能!
    def get(self, request):
        pass

写一次,到处用。这不就是程序员梦寐以求的“偷懒”境界吗?

3. Mixin:像搭积木一样组合功能

Django类视图最强大的地方在于Mixin机制。你可以把各种功能写成独立的Mixin类,然后按需组合:

# 记录操作日志的Mixin
class LoggingMixin:
    def dispatch(self, request, *args, **kwargs):
        print(f"{request.method}请求到达:{request.path}")
        return super().dispatch(request, *args, **kwargs)

# 缓存Mixin
class CacheMixin:
    cache_timeout = 60
    
    def get_cache_key(self, request):
        return f"view_{request.path}"

class ArticleView(LoggingMixin, CacheMixin, View):
    # 这个视图同时拥有了日志和缓存功能!
    pass

这种感觉就像吃自助餐,想要什么功能就“夹”什么功能到你的视图里。

二、实战开始:用类视图重写博客API

光说不练假把式,让我们一步步把一个传统的函数视图博客API改造成类视图版本。

改造前:函数视图版博客API

# 旧的views.py
def article_list(request):
    if request.method == 'GET':
        articles = Article.objects.all()
        return JsonResponse({
            'articles': list(articles.values('id', 'title', 'created_at'))
        })
    
    elif request.method == 'POST':
        try:
            data = json.loads(request.body)
            article = Article.objects.create(
                title=data['title'],
                content=data['content'],
                author=request.user
            )
            return JsonResponse({'id': article.id}, status=201)
        except KeyError:
            return JsonResponse({'error': '缺少必要字段'}, status=400)
    
    else:
        return JsonResponse({'error': '方法不允许'}, status=405)

def article_detail(request, article_id):
    try:
        article = Article
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

值引力

持续创作,多谢支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值