代码之家  ›  专栏  ›  技术社区  ›  Dhruv Marwha

在Django REST和Django中对单个数据库中的多个模型执行多个插入/更新

  •  0
  • Dhruv Marwha  · 技术社区  · 7 年前

    我在Django有两个模特。A型和B型。这是这两个模型的代码(这只是示例代码)

    class ModelA(models.Model):
        # Single Insert
        name=model.CharField(max_length=100)
    
    class ModelB(models.Model):
        # Multiple Insert
        model_a=models.ForeignKey(ModelA,on_delete=models.CASCADE)
        address=models.CharField(max_length=250)
    

    现在,我如何使用Django中的ORM在这两个模型中使用单个数据库查询(即数据库应该只被命中一次)插入数据。更具体地说,可以通过Django REST序列化器这样做,因为它可以以优化的方式处理CRUD操作。

    我知道我可以通过多个序列化器来实现,但这将导致数据库多次被命中,或者我也可以通过MySQL中的存储过程来实现。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Satendra    7 年前

    你可以利用 bulk_create bulk_update 方法,您需要手动创建对象列表。

    对你来说 ModelA 是父类和 ModelB 是个孩子。

    意思是 模型A 可以与多个对象相关 属于 模型B

    如果你有 request.data 在您的API端点中似乎是这样。

    received_data = [
      {
        "name": "model_a_obj_1",
        "children": [
          {
            "address" : "some_address"
          }, 
          {
            "address" : "some_other_address"
          }
        ] 
      }, {}, {}, ...
    ]
    

    现在,第一步是创建两个列表,一个是子列表,一个是父对象列表。

    model_a_obj_list = []
    model_b_children_list = []
    
    for obj in received_data:
       children_list = []
       for child in obj.children:
          children_list.append(ModelB(**child))
       model_b_children_list.append(children_list)
       model_a_obj_list.append(ModelA(name=obj.name))
    

    现在,首先创建父对象,即ModelA,然后循环ModelA的实际对象以指定 pk 到相应的ModelB对象

    model_a_objs = ModelA.objects.bulk_create(model_a_obj_list)
    
    model_b_obj_list = []
    for i, a_obj in enumerate(model_a_objs):
        model_b_obj_sub_list = model_b_children_list[i]
        for b_obj in model_b_obj_sub_list:
            b_obj.model_a = a_obj
            model_b_obj_list.append(b_obj)
    

    现在我们有了带有ModelA引用的ModelB对象。现在只需创建ModelB对象。

    ModelB.objects.bulk_create(model_b_obj_list)
    

    记住 批量创建 方法不使用 .save() 模型类的方法,所以 post_save 创建对象列表时必须计算逻辑 批量创建

    这个解决方案将达到每种型号的DB 2次

    推荐文章