在Django开发中你需要知道Class

4,280 阅读3分钟

MedusaSorcerer的博客


描述内容

在Django开发WEB项目的时候我们一般情况下使用继承View类来实现基本的API视图调度, 当然你可以实现你的需求, 但是在你实现功能的时候需要撰写很多代码来做限制以及预判, 基本都是以这样的形式撰写:

from django import views

class Medusa(views.View):
    def get(self, request, *args, **kwargs):
        pass

包括你使用全栈的前后端不分离的写法可能也会包含很多代码, 那么有什么更好的办法来解决么? 脱离繁琐负重的判断控制代码, 用更加简介的方式撰写一个可用安全高效的RestfulAPI?

高效解决方案

假设你现在使用的是标准的RestfulAPI开发撰写JSON数据返回, 那么我非常推荐你使用django_rest_framework, 它包含参数判断控制/用户认证/全选管控/数据过滤/请求分离集成/可视化API文档等等, 这已经在很多JSONAPI中达到很高的使用量, 然而你使用的时候仅仅需要这样撰写:

from rest_framework import mixins

class MedusaViewSet(mixins.ListModelMixin, mixins.DestroyModelMixin, mixins.CreateModelMixin, mixins.UpdateModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    def list(self, request, *args, **kwargs):
        """GET请求列表数据"""
        pass
    
    def update(self, request, *args, **kwargs):
        """PUT更新数据"""
        pass
    
    def delete(self, request, *args, **kwargs):
        """DELETE删除数据"""
        pass
        
    def create(self, request, *args, **kwargs):
        """POST新增数据"""
        pass
        
    def retreve(self, request, *args, **kwargs):
        """GET请求详情数据"""
        pass

当你继承某一个Class就可以通过重写该Class下对应的方法实现你所需要的具体内容, 当然了他还可以通过指定各种属性的值实现其他内容的约束, 例如queryset = model.objects.all()来声明这个ViewSet是请求那个表的数据, 其他参数可以查阅其官方文档, 后期还会更新一则关于Rest_framework的博文。

那么相对的, 前后端不分离的情况下我们又该怎么样简化自己的代码呢? 那前后端不分离的时候HTML语言也是可以封装的, 这儿稍微提一下: 如我在Django项目中templates下新建一个basic.html作为基本界面的框架, 具体内容我仅仅需要向里面增加标签以及内容即可:

<!DOCTYPE HTML>

<html lang="en">
<head>
    <title>MedusaSorcerer-Blog</title>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1"/>
    <link rel="stylesheet" href="/static/css/main.css"/>
    <link rel="stylesheet" href="/static/css/cool.css">
    {% block header %}

    {% endblock %}
</head>

<body>
    {% block body %}

    {% endblock %}
    <script src="/static/js/jquery.min.js"></script>
    <script src="/static/js/jquery.scrollex.min.js"></script>
    <script src="/static/js/jquery.scrolly.min.js"></script>
    <script src="/static/js/skel.min.js"></script>
    <script src="/static/js/util.js"></script>
    <!--[if lte IE 8]>
    <script src="/static/js/ie/respond.min.js"></script><![endif]-->
    <script src="/static/js/main.js"></script>
</body>
</html>

那么我们仅仅需要使用基本模板basic.html后填塞body部分, 或者有需求的可以填塞header部分:

{% extends "basic.html" %}

{% block header %}
    <!--你需要填充的header部分代码-->
{% endblock %}

{% block body %}
    <!--你需要填充的body部分代码-->
{% endblock %}

这样你的HTML就是继承模板重新填充的新HTML文件, 那么现有一个index.html静态文件, 我们怎么用简单的代码进行静态文件访问API的撰写呢?

from django.views.generic import TemplateView


class TemplateViewSet(TemplateView):
    template_name = 'bloglist.html'

就这么简单, 一个界面API撰写完成了, 那么又有问题了, 如果我们的界面存在这样的变量{{ data.name }}, 我们怎么传递参数?

# 在 TemplateViewSet 中实现实例方法

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context['data'] = dict(name='Medusa')
    return context

那如果我在get_context_data实现判断并重定向可以么? 答案是不可以, 该方法只能返回Dict类型数据, 那么这样的需求在哪儿实现?

from django.http import HttpResponseRedirect

# 在 TemplateViewSet 中实现实例方法

def dispatch(self, request, *args, **kwargs):
    return super().dispatch(request, *args, **kwargs) if kwargs.get('sign') == 'medusa' else HttpResponseRedirect('/notfound')

在Django框架中, 很多可以供我们使用的轮子, 放我们摆脱沉重复杂且冗余的代码块, 这样简单的几行代码便可以实现很多复杂功能。