POST请求以使用csv文件中的批量数据创建资源

时间:2018-07-10 12:24:02

标签: python django rest django-rest-framework

我在许多项目中都使用过 Python ,但是我对 django django rest框架是陌生的为我当前的项目设计和开发一组Web API。

编织后端,我们将 Postgres 用于用户信息,将 DynamoDb 用于用户必须使用的其他资源。

在基本实现中,我尝试按如下方式编写视图集:

class WorkViewSet(viewsets.ViewSet):
    serializer_class = serializers.WorkSerializer
    permission_map = {
        'create'             : [IsAuthenticated, IsUser, ],  # post
        'list'               : [IsAuthenticated, ],          # get
        'retrieve'           : [IsAuthenticated, ],          # get
        'work_approval'      : [IsAuthenticated, IsAdmin, ], # post
        'work_disapproval'   : [IsAuthenticated, IsAdmin, ], # post
    }

    def list(self, request):
        ...

    def create(self, request):
        ...

    def retrieve(self, request, pk=None):
        ...

    @action(methods=['post'], detail=True, url_path='approve', url_name='work_approval')
    def work_approval(self, request, pk=None, *args, **kwargs):
        ...

    @action(methods=['post'], detail=True, url_path='disapprove', url_name='work_disapproval')
    def work_disapproval(self, request, pk=None, *args, **kwargs):
        ...

    def get_permissions(self):
        try:
            return [permission() for permission in self.permission_map[self.action]]
        except KeyError:
            return [permission() for permission in self.permission_classes]

和以下序列化器:

class WorkSerializer(serializers.Serializer):
    STATUSES = (
        '0',
        '1',
        '2',
    )
    work_id     = serializers.IntegerField(read_only=True)
    work_name   = serializers.CharField(max_length=256)
    work_type   = serializers.CharField(max_length=256)
    work_status = serializers.ChoiceField(choices=STATUSES, default='0')

    def create(self, validated_data):
        ...

    def update(self, instance, validated_data):
        ...

这组代码对我来说绝对正常,但是随着最新要求的更改,我需要配置POST请求以另外接受一个csv文件并解析此文件以提取必须在其他字段中推送到数据库的内容(不作为文件字段)。我试图寻找解决此问题的方法并找到了link,但该解决方案主要针对与我的需求不同的单一类型资源的批量提交。

我正在使用 Python 3.6.5 Django 2.0.6 Django Rest Framework 3.8.2

请帮助我如何进行。

1 个答案:

答案 0 :(得分:0)

扩展序列化器以包含CSV文件:

class WorkSerializer(serializers.Serializer):
    csv_file = serializers.FileField()

在序列化程序的创建函数中:

 def create(self, validated_data):
     csv_input = validated_data.pop("csv_file", None)
     instance = super().create(validated_data)

     if csv_input: 
          ** Process your csv file **

     return instance 

就个人而言,我建议您创建一个背景来处理csv文件并更新数据库。因为这可能是长期运行的任务。 因此,您可以安排任务,而不是在POST请求期间直接处理csv文件。

已更新为回答评论

背景处理-只需进行少量配置,您可以选择多种方式。也许,最简单的方法是使用django background tasks 这将很好地满足您的目的。您只需创建一个函数,添加背景装饰器,然后在调用它时就计划了任务。

  

您认为这种使用csv文件发布批量数据的方法是一种好方法还是应该使用巨大的json?

这取决于。

如果上载文件,则需要为其配置存储设备,计划任务可以访问该存储设备(本地或远程任务,再次取决于您的用例)。 一个巨大的json-hm,这取决于有多大。您需要运行一些测试以确定您的限制在哪里。

也许一种可能的解决方案是将csv文件直接从客户端上传到您的存储中(如果您使用的是S3,这很容易),然后告诉服务器从那里进行处理。