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

标签 python django rest django-rest-framework

我在我的许多项目中都使用了 Python,但我是 djangodjango rest 框架的新手,我正在使用它来为我当前的项目设计和开发一组 Web API。

编织后端,我们使用 Postgres 获取用户信息,使用 DynamoDb 获取用户必须处理的其他资源集。

在基本实现中,我尝试编写如下 View 集:

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.5Django 2.0.6Django Rest Framework 3.8.2

请帮助我应该如何进行。

最佳答案

扩展序列化程序以包含 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 这将很好地满足您的目的。您只需创建一个函数,添加背景装饰器,当它被调用时,就会安排一个任务。

Do you think if this approach of using a csv file to post bulk data is a good one or we should use a huge json instead ?

那要看情况了。

如果您上传一个文件,您将需要为其配置一个您的计划任务可以访问的存储(本地或远程,同样取决于您的用例)。 一个巨大的 json - 嗯,这取决于它有多大。您需要运行一些测试以确定您的极限在哪里。

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

关于python - POST 请求使用 csv 文件中的批量数据创建资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51265127/

相关文章:

python - 通过Web界面修改系统配置文件和使用系统命令

python - 我应该在服务器端渲染 ajax 响应吗?

python - 在运行 centos/whm 的服务器中更新 python?

rest - 使用 HBase REST API 过滤

java - CRest日志请求/响应体

Python 3 异步 : run_until_complete() blocks when waiting for ProcessPoolExecutor job done

python - matplotlib 可选择在左侧或右侧自动缩放轴范围

python - 如何在 Django 模板中使用后删除 session 变量

python - 如何编写一个以字典键作为列名、以字典值作为列值的Excel文件?

c# - 我可以在 RESTful 服务中使用 TCP 吗?