博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
通过view实现rest api接口
阅读量:6539 次
发布时间:2019-06-24

本文共 11233 字,大约阅读时间需要 37 分钟。

Django rest framwork之view

基于Django的View实现Json数据的返回:

# _*_ encoding:utf-8 _*___author__ = 'LYQ'__data__ = '2018/8/13 15:21'import jsonfrom django.views.generic.base import Viewfrom django.http import HttpResponse,JsonResponsefrom .models import *class GoodsView(View):    def get(self,request):       good_list=Goods.objects.all()[:10]       datas=[]       # for good in good_list:       #     json_dict = {}       #     json_dict['name']=good.name       #     json_dict['goods_desc']=good.goods_desc       #     json_dict['category']=good.category.name       #     json_dict['shop_price']=good.shop_price       #     #时间不是json序列化的对象       #     json_dict['time']=good.add_time       #     datas.append(json_dict)       #直接序列化       from django.forms.models import model_to_dict       #用来做序列化       from django.core import serializers       datas=[]       for good in good_list:           #image和datetime不能序列化          data=model_to_dict(good)          datas.append(data)       datas=serializers.serialize('json',good_list)       datas=json.loads(datas)       # return HttpResponse(datas,content_type='application/json')       return JsonResponse(datas,safe=False)

 Django rest framwork的简单介绍及安装(可参考官方网站):

Django REST框架是用于构建Web API的强大而灵活的工具包。

您可能希望使用REST框架的一些原因:

  • 该是你的开发人员一个巨大的可用性胜利。
  • 包括和程序包。
  • 支持和数据源的。
  • 可自定义 - 如果您不需要只需使用。
  • 和。
  • 受到国际知名公司的使用和信任,包括,,和。

REST框架需要以下内容:

  • Python(2.7,3.4,3.5,3.6,3.7)
  • Django(1.11,2.0,2.1)

以下包是可选的:

  • (1.32.0+) - 模式生成支持。
  • (2.1.0+) - Markdown对可浏览API的支持。
  • (1.0.1+) - 过滤支持。
  •  - 改进的HTML显示以进行过滤。
  • (1.1.1+) - 对象级权限支持。

 

使用安装pip,包括您想要的任何可选包...

pip install djangorestframeworkpip install markdown       # Markdown support for the browsable API.pip install django-filter # Filtering support

...或者从github克隆项目。

git clone git@github.com:encode/django-rest-framework.git

添加'rest_framework'到您的INSTALLED_APPS设置。

INSTALLED_APPS = ( ... 'rest_framework', )

如果您打算使用可浏览的API,您可能还需要添加REST框架的登录和注销视图。将以下内容添加到根urls.py文件中。

urlpatterns = [ ... url(r'^api-auth/', include('rest_framework.urls')) ]

请注意,URL路径可以是您想要的任何内容。

让我们看一个使用REST框架构建一个简单的模型支持的API的快速示例。

我们将创建一个读写API,用于访问有关项目用户的信息。

REST框架API的任何全局设置都保存在名为的单个配置字典中REST_FRAMEWORK。首先将以下内容添加到settings.py模块中:

REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions, # or allow read-only access for unauthenticated users. 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly' ] }

别忘了确保你也加入rest_frameworkINSTALLED_APPS。我们现在准备创建我们的API了。

注:如果出现utf8 decode的错误,把虚拟环境中的\Lib\site-packages\pip\compat中的_init_.py的75行中的utf8改成gbk从新安装即可。

一.ApiView方式实现api

    1.serializers:

#form对应:Serializer,modelform:ModelSerializerfrom rest_framework import serializersfrom .models import *class GoodsSerializer(serializers.Serializer):    name = serializers.CharField(required=True,max_length=100)    click_num = serializers.IntegerField(default=0)    goods_front_image=serializers.ImageField()    add_time=serializers.DateTimeField()    def create(self, validated_data):        return Goods.objects.create(**validated_data)

 

    2.views:    

from rest_framework.views import APIView #状态码 from rest_framework import status from .models import *from .serializers import GoodsSerializer from rest_dramework.response import Reaponseclass GoodsListView(APIView):    """    List all snippets, or create a new snippet.    """    def get(self, request, format=None):        goods = Goods.objects.all() #many=True,goods是一个列表        goods_serializer = GoodsSerializer(goods, many=True)        return Response(goods_serializer.data)    def post(self,request,format=None):        serializer=GoodsSerializer(data=request.data) #验证字段是否合法        if serializer.is_valid():           serializer.save()           return Response(request.data,status=status.HTTP_201_CREATED)        return Response(request.data,status=status.HTTP_400_BAD_REQUEST)

 

 

    3.ModelSerializer:

class GoodsSerializer(serializers.ModelSerializer):    # 替换默认的category    category = GoodsCategorySerializer()    # 可能有多条many=True    images = GoodsImageSerializer(many=True)    class Meta:        model = Goods        # fields=('name','click_num','market_price','add_time','goods_front_image')        # 外键为id,想要完整信息,嵌套Serializer        fields = ('__all__')

 

二.GenericView方式实现api接口

from rest_framework import mixinsfrom rest_framework import generics#基于mixins,必须重载get函数 class GoodsListView(mixins.ListModelMixin,generics.GenericAPIView):     """     商品详情页     """     queryset = Goods.objects.all()[:10]     serializer_class = GoodsSerializer     #必须重写,不然默认无法接受get请求     def get(self, request, *args, **kwargs):         return self.list(request, *args, **kwargs)

 

三.Viewset和router实现api接口和配置

    1.viewset中的view:

    2.GenericViewset:

    继承了ViewSetMixin和GenericAPIView,ViewSetMixin重写了as_view方法,initialize_request方法,initialize_request方法设置了很多action,在动态使用serializer时有很多的好处

 

class ViewSetMixin(object):    """    This is the magic.    Overrides `.as_view()` so that it takes an `actions` keyword that performs    the binding of HTTP methods to actions on the Resource.    For example, to create a concrete view binding the 'GET' and 'POST' methods    to the 'list' and 'create' actions...    view = MyViewSet.as_view({'get': 'list', 'post': 'create'})    """    @classonlymethod    def as_view(cls, actions=None, **initkwargs):        """        Because of the way class based views create a closure around the        instantiated view, we need to totally reimplement `.as_view`,        and slightly modify the view function that is created and returned.        """        # The suffix initkwarg is reserved for displaying the viewset type.        # eg. 'List' or 'Instance'.        cls.suffix = None        # The detail initkwarg is reserved for introspecting the viewset type.        cls.detail = None        # Setting a basename allows a view to reverse its action urls. This        # value is provided by the router through the initkwargs.        cls.basename = None        # actions must not be empty        if not actions:            raise TypeError("The `actions` argument must be provided when "                            "calling `.as_view()` on a ViewSet. For example "                            "`.as_view({'get': 'list'})`")        # sanitize keyword arguments        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" % (                    cls.__name__, key))        def view(request, *args, **kwargs):            self = cls(**initkwargs)            # We also store the mapping of request methods to actions,            # so that we can later set the action attribute.            # eg. `self.action = 'list'` on an incoming GET request.            self.action_map = actions            # Bind methods to actions            # This is the bit that's different to a standard view            for method, action in actions.items():                handler = getattr(self, action)                setattr(self, method, handler)            if hasattr(self, 'get') and not hasattr(self, 'head'):                self.head = self.get            self.request = request            self.args = args            self.kwargs = kwargs            # And continue as usual            return self.dispatch(request, *args, **kwargs)        # 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=())        # We need to set these on the view function, so that breadcrumb        # generation can pick out these bits of information from a        # resolved URL.        view.cls = cls        view.initkwargs = initkwargs        view.suffix = initkwargs.get('suffix', None)        view.actions = actions        return csrf_exempt(view)    def initialize_request(self, request, *args, **kwargs):        """        Set the `.action` attribute on the view, depending on the request method.        """        request = super(ViewSetMixin, self).initialize_request(request, *args, **kwargs)        method = request.method.lower()        if method == 'options':            # This is a special case as we always provide handling for the            # options method in the base `View` class.            # Unlike the other explicitly defined actions, 'metadata' is implicit.            self.action = 'metadata'        else:            self.action = self.action_map.get(method)        return request    def reverse_action(self, url_name, *args, **kwargs):        """        Reverse the action for the given `url_name`.        """        url_name = '%s-%s' % (self.basename, url_name)        kwargs.setdefault('request', self.request)        return reverse(url_name, *args, **kwargs)    @classmethod    def get_extra_actions(cls):        """        Get the methods that are marked as an extra ViewSet `@action`.        """        return [method for _, method in getmembers(cls, _is_extra_action)]

    3.继承genericviewset的view写法:

      GenericViewSet继承于GnericAPIView,没有重写get,post等方法,因此还需要继承mixin

class GoodsListViewSet(mixins.ListModelMixin,mixins.RetrieveModelMixin,viewsets.GenericViewSet):    """    商品详情页,分页,搜索,过滤,排序    """    #配置ip限制访问次数    throttle_classes = (UserRateThrottle,AnonRateThrottle)    queryset = Goods.objects.all()    serializer_class = GoodsSerializer    #分页    pagination_class = GoodsPagination    #配置认证类,防止公开网页(未登录可查看)不能访问    # authentication_classes = (TokenAuthentication,)    filter_backends=(DjangoFilterBackend,filters.SearchFilter,filters.OrderingFilter)    #字段过滤(DjangoFilterBackend)    # filter_fields = ('name', 'shop_price')    filter_class=GoodsFilter    #搜索过滤(rest_framework.filters.SearchFilter)    search_fields = ('name','goods_brief','goods_desc')    #排序过滤(rest_frameworkfilters.OrderingFilter)    ordering_fields = ('sold_num', 'shop_price')    def retrieve(self, request, *args, **kwargs):        instance = self.get_object()        instance.click_num+=1        instance.save()        serializer = self.get_serializer(instance)        return Response(serializer.data)

 

     viewset和router配套使用:

      第一种:配置url:

1 #在url.py文件中   2 #配置GoodsListViewSet 3  good_list=GoodsListViewSet.as_view({ 4 #把get请求绑定到list方法上 5          'get':'list', 6      }) 7 urlpatterns = [ 8 #把good_list放入url中 9  url('^goods/$',good_list,name='good_list'),11 ]

 

 

        第二种:(使用router)

from rest_framework.routers import DefaultRouterrouter = DefaultRouter()# 配置goods的urlrouter.register(r'goods', GoodsListViewSet, base_name='goods')#在调用router.urls时会自动把router中转换为url配置urlpatterns = [url('^', include(router.urls)),]

 

四.View继承关系

    1.View继承关系(差异就是不同的mixin):

        GnericViewSet(drf)【比GnericAPIView继承增加了一个ViewSetMixin,在url中绑定了,router可以使用,还有实现了initialize_request方法设置了很多action方便不同serializer的使用】———>GnericAPIView(drf)【增加了筛选过滤分页,serializer等】———>APIView(drf)———>View(django)

    2.mixin:

  CreateModelMixin

  ListModelMixin

  RetrieveModelMixin

  UpdateModelMixin

  DestroyModelMIxin

  意境定制好了的view组合(继承GericAPIView不同的mixin实现不同的功能):

 

转载于:https://www.cnblogs.com/lyq-biu/p/9625896.html

你可能感兴趣的文章
mysql 缓存开启及测试
查看>>
自己写的进度条###
查看>>
windows磁盘扩容(动态磁盘)
查看>>
在jsp页面中添加富文本编译器(ueditor)+ 图片上传功能
查看>>
fedora12下安装oracle11客户端
查看>>
实现批量添加20个用户,用户名为user1-50,密码为user后面跟5个随机字符
查看>>
LVM磁盘管理
查看>>
Net命令详解
查看>>
CentOS linux 高可用集群之heartbeat
查看>>
用bat更改hosts文件批处理
查看>>
Logwatch日志分析工具
查看>>
docker 基本操作Ⅱ(关于镜像操作)
查看>>
分工與合作
查看>>
轻松设置站点对ASP危险组件的调用权限
查看>>
看懂“拜占庭容错”,也就看懂了区块链的核心技术
查看>>
APMServ 5.2.6 Win7 Apache启动失败,请检查相关配置
查看>>
了解痘痘起因才能彻底告别痘痘烦恼
查看>>
Zabbix安装
查看>>
Java 日志 详解
查看>>
openstack虚拟化技术和镜像制作
查看>>