【问题标题】:What is the correct way of saving 200 objects in the database using django-rest-framework?使用 django-rest-framework 在数据库中保存 200 个对象的正确方法是什么?
【发布时间】:2019-06-01 04:54:29
【问题描述】:

我有一个问题要在下周的项目中解决。我有一个包含 3 个字段的模型,其中 2 个是其他模型的外键,另一个字段是一个简单的字符串字段。在前端,我将只向用户展示一个复选框和一个观察字段,一个可以为空或空的字符串字段。将有一个复选框列表,大约 200 个。每个复选框都是数据库中的一个对象。我不想为他们每个人都发出一个post请求,这会让用户体验很糟糕,200个字段已经很糟糕了,但在这种情况下是必要的。

所以我想要一些建议和代码示例,了解实现这一目标的最佳方法。这是模型。

class Person(models.Model):
    observation = models.TextField(blank=True, null=True)
    country = models.ForeignKey(Country, on_delete=models.PROTECT)
    user = models.ForeignKey(User, on_delete=models.PROTECT)

我有一个序列化程序和一个 ModelViewSet 使用单个请求为它工作,1 个对象的 POST 请求正在工作。

class PersonSet(viewsets.ModelViewSet):
    queryset = Person.objects.all()
    serializer_class = PersonSerializer

我希望前端向后端发送一个大列表/数组/对象,不确定,后端在单个 POST 请求中获取所有数据并启动进程以将其保存在数据库。我在想,如果最好的方法是遍历这些数据并在视图内的每个数据上调用序列化程序,或者我会实现一种新型的序列化程序来实现它。
我已经阅读了question1question2 这两个问题,这确实很有帮助,但我仍然有疑问。还有另一个问题,如果发生错误,比如假设服务器在进程中间出现故障,连接被中断,发生了一些事情,那么我的数据将被保存或在中间被中断,我在问因为我无法分离这些数据,所以我需要保证全部 200 个字段被保存或 0 个字段被保存。

【问题讨论】:

  • 澄清一下,使用的模型只是一个例子,不是真实案例。
  • 我们能否看到您将发送的示例 json。或者只是为您的示例模型制作 json
  • 示例模型就可以了,真实模型不同,但是值的类型是一样的。

标签: json django serialization django-rest-framework nested-loops


【解决方案1】:

您可以将数据列表传递给序列化器,并通过将多个参数传递给序列化器来一次验证所有数据

example_data = [
 {'country': 1, 'user': 1, 'observation': ''},
 {'country': 1, 'user': 2, 'observation': ''},
 {'country': 2, 'user': 1, 'observation': ''},
 {'country': 2, 'user': 2, 'observation': ''},
]

serializer = PersonSerializer(data=example_data, many=True)

if serializer.is_valid():
    serializer.save()

当且仅当所有数据实例都有效并且将为数据中的每个数据创建对象时,它才有效。

如果您担心数据库级别的故障,您可以随时在序列化程序的 create 方法中使用原子事务。

from django.db import transaction


class PersonSerializer(serializer.ModelSerializer):
    ...

    def create(self, validated_data):
        with transaction.atomic():
            return super().create(validated_data)

【讨论】:

  • 我做错了什么,因为它传入serializer.is_valid(),然后传入serializer.save(),但是当我检查数据库时,数据不存在,作为回应,我什么也没得到,一个空括号[]。我是否需要覆盖序列化程序中的create()
猜你喜欢
  • 2015-10-01
  • 2018-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-25
相关资源
最近更新 更多