Django rest framework 如何使用嵌套模型在django REST框架中进行批量创建?

Django rest framework 如何使用嵌套模型在django REST框架中进行批量创建?,django-rest-framework,Django Rest Framework,我对DRF比较陌生,我正试图找出这个问题,它似乎与我能找到的所有文档略有不同。在我的玩具示例中,假设我有一个模型中数十万人的记录,另一个模型拥有他们所有的汽车,另一个模型拥有他们所有的其他财产: class Person(models.Model): first_name = models.CharField() last_name = models.CharField() zipcode = models.IntegerField() favorite_colo

我对DRF比较陌生,我正试图找出这个问题,它似乎与我能找到的所有文档略有不同。在我的玩具示例中,假设我有一个模型中数十万人的记录,另一个模型拥有他们所有的汽车,另一个模型拥有他们所有的其他财产:

class Person(models.Model):
    first_name = models.CharField()
    last_name = models.CharField()
    zipcode = models.IntegerField()
    favorite_color = models.CharField()
    class Meta:
        unique_together = ('first_name', 'last_name', 'zipcode', 'favorite_color')

class Car(models.Model):
    person = models.ForeignKey(Person)
    carmake = models.CharField()
    carmodel = models.CharField()
    VIN = models.CharField()

class OtherProperty(models.Model):
    person = models.ForeignKey(Person)
    prop_type = models.CharField()
    prop_value = models.Integer()
假设我已经在数据库中加载了所有的人。现在我有一大批一万人购买新车的新记录。有些人买了多辆车,有些人不买车。我想制作一个功能强大的API,并使客户端程序保持简单,因此我想直接上传(通过POST调用)所有购买的新车。诀窍在于客户端程序没有每个Person记录的唯一主键。因此,我希望客户端提交一个类似以下内容的json帖子:

[ {'person' : {'first_name':'Joe', 
               'last_name': 'Smith',
               'zipcode': 80110,
               'favorite_color': 'Blue'},
   'carmake' : 'Subaru',
   'carmodel' : 'Outback',
   'VIN' : 12345123123},
  {'person' : {'first_name':'Amy', 
               'last_name': 'Adams',
               'zipcode': 92075,
               'favorite_color': 'White'},
   'carmake' : 'BMW',
   'carmodel' : '325ic',
   'VIN' : 987165334},
   .... 10,000 more records... ]
现在,我有了一个解决方案,我使用views.py读取request.data,验证Person字段是否包含已验证的内容,向Person模型写入QuerySet,将所有Person主键加载到dict中,如果不是所有Person实例都已存在,则返回错误。然后我根据request.data创建一个新的dict,但是所有的person子dict都被新找到的主键替换。然后我调用CarSerializer,它有一个使用django函数bulk_create(根据文档:)的list_serializer_类的元字段。这很有效

但是,我认为个人查找代码不属于汽车视图集中,对吗?而且,我可能重复了django/DRF在验证方面已经完成的许多工作。此外,现在我需要将该代码复制并粘贴到OtherProperty视图集中,以执行同一个人的主键查找。事实上,我有更多的模型有一个ForeignKey到Person模型,我知道我不应该复制/粘贴所有主键查找和验证代码

所以,我的问题是,我可以把那个人的主键查找代码放在哪里?这似乎是序列化程序应该做的事情,但我不想保存任何新的Person实例。而且,由于我正在创建大量的“Cars”(或“OtherProperty”)实例,我需要一个ListSerializer(bulk_create)调用,所以我不认为我可以仅仅依赖嵌套关系并期望它工作。我是否错过了一个显而易见的解决方案

谢谢你的建议

编辑

我有几个想法作为可能的解决方案:

  • 创建未附加到Person模型的PersonLookup序列化程序。此序列化程序将具有Person字段,接收完整的request.data并使用序列化程序功能进行验证,但不创建任何记录,它将返回带有PKs的原始request.data,而不是详细的人员信息,这样返回的数据可以由ViewSet处理并发送到Car或其他属性序列化程序

  • 将唯一字段添加到Person模型,该模型是所有非唯一字段的下划线分隔串联。然后,客户端将能够通过连接创建这些字段,并且request.data将不会嵌套。实际上,这可能不起作用,因为bulk_create需要主键,而不是一些唯一的字段,我认为(?)。另一个问题是,我将存储所有Person字段两次,一次存储在唯一名称中,另一次存储在单个字段中。也许有一个管理者的诀窍可以解决这个问题

  • 所以我不认为我可以仅仅依靠嵌套关系并期望它工作

    不,你不能。因为DRF(从版本3.0开始)不再支持任何类型的嵌套创建/更新(请参见“”

    至于你的问题,你的做法是可行的。唯一可能的改进是缓存你的个人pk,以供进一步使用。这样,在创建汽车时,你只需要访问数据库一次。之后,将从缓存中检索每个人的pk


    希望这能有所帮助。

    此主题类似,可能重复: