繁体   English   中英

使用Django和Django rest框架创建和使用API

[英]Creating and consuming an API using Django and the Django rest framework

我正在使用django和django rest框架构建API。 我还在构建一个将使用此API的系统(也是Django)。

我对如何在两个服务器上实现序列化器感到有些困惑。 到目前为止,我已经在两台服务器上实现了输入和输出串行器。 下面的代码示例显示了这些序列化器的简单示例。 它需要一个日期和几天的天数,然后进行计算并返回一个新日期和两个日期之间的假期数(代码实际上并未对此进行计算)。

我在4个地方调用序列化程序,每次还必须调用is_valid()方法。 我不确定是否需要所有这些序列化程序和对is_valid的调用。 一切正常,但似乎有点笨拙。 话虽如此,我不确定还有其他替代方法,特别是因为我需要序列化日期。 我想我可以为日期实现自己的序列化器,但似乎我正在重新发明轮子。 还有一个问题是要确保序列化类在两个服务器之间保持不变。

我的问题是,当我既是API的创建者又是消费者时,应该遵循一种推荐的方法吗? 我需要所有这些序列化器吗? 如果没有,我可以丢掉哪一个,应该用什么替换?

请注意,在我的实际代码中,序列化程序中有许多嵌套字段,因此它不像本例那样简单。

在我的API服务器上,我有以下内容:

from rest_framework import views, serializers
from django.views.decorators.csrf import csrf_exempt
from rest_framework.decorators import api_view

class MyInputSerializer(serializers.Serializer):
    my_date = serializers.DateField()
    days = serializers.IntegerField()

    def do_calc(self):
        my_date = self.validated_data.get('my_date')
        days = self.validated_data.get('days')

        calc_date = my_date  # just as an example
        holidays = days - 2  # just as an example
        result = {
                  'calc_date': calc_date,
                  'holidays': holidays,
                  }
        return MyOutputSerializer(data=result)

class MyOutputSerializer(serializers.Serializer):
    calc_date = serializers.DateField()
    holidays = serializers.IntegerField()


@csrf_exempt
@api_view(['POST'])
def test(request): #/api/v1.0/calc/ maps to this function
    data=request.data
    serializer = MyInputSerializer(data=data)
    if serializer.is_valid(raise_exception=True):
        result = serializer.do_calc()
        if result.is_valid(raise_exception=True): #should always be valid? Needed to access result.data
            return JsonResponse(result.data)

在普通的Django网络服务器上,我有以下内容:

from rest_framework import serializers
from datetime import date
import requests

class MyInputSerializer(serializers.Serializer):
    # same fields as above
    my_date = serializers.DateField()
    days = serializers.IntegerField()


class MyOutputSerializer(serializers.Serializer):
    # same fields as above
    calc_date = serializers.DateField()
    holidays = serializers.IntegerField()


def testing():
    MY_SERVER_URL = 'http://127.0.0.1:8888/api/v1.0/calc/'
    data = {
            'my_date': date(2016, 2, 2),
            'days': 10,
            }
    serializer = MyInputSerializer(data=data)
    if serializer.is_valid(raise_exception=True):
        post_result = requests.post(MY_SERVER_URL, json=serializer.data)
        result = MyOutputSerializer(data=post_result.json())
        if result.is_valid(raise_exception=True):  # This needed?
            calc_date = result.validated_data.get('calc_date')
            holidays = result.validated_data.get('holidays')
            return calc_date, holidays

另一件事,我可以在具有DB的服务器上创建ModelSerializer,但是随后我需要在另一台服务器上重新创建普通的序列化器以反序列化数据。 这种否定了ModelSerializer的优势。 通常情况下,该如何处理?

序列化程序应该只做一件事:序列化数据。 他们不应实施任何业务逻辑。 据我了解您的代码示例, do_calc正在实现业务逻辑。 此外,这不是正确的位置,您实际上返回了另一个串行器的输出。 此代码属于视图。

简而言之,我现在根本不理解为什么要使用DRF串行器。 您是要使用该框架,还是只是滚动自己的逻辑,就可以了。 如果仅具有这两个值,那么序列化就没什么用(除非您的示例完全缩短了)。

is_valid仅在要更新和创建模型实例时使用。 函数do_calc不是使用to_representation序列化模型并在其中进行工作的正确方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM