【问题标题】:Django Rest Framework: Call serializer.save using double underscoreDjango Rest Framework:使用双下划线调用 serializer.save
【发布时间】:2018-07-31 19:42:33
【问题描述】:

在 Django 中创建查询集时,您可以使用双下划线方法来过滤模型的特定条件: 例如。而不是像这样通过他们的pk过滤餐厅:

restaurants = Restaurant.objects.filter(restaurant=<some_pk>)

您可以通过模型的某些属性过滤它们,如下所示:

restaurants = Restaurant.objects.filter(restaurant__uuid=<some_uuid>)

或者

restaurants = Restaurant.objects.filter(restaurant__name=<some_name>)

现在在 api 视图中的函数中(例如在 get_queryset 中)你可以使用它来过滤请求的 kwargs:

def get_queryset(self):
    restaurants = Restaurant.objects.filter(restaurant__uuid=self.kwargs['uuid'])
    return restaurants

现在我想使用 serializer.save() 来做同样的事情。在我的表演中,我想调用:

def perform_create(self, serializer):
    serializer.save(restaurant__uuid=self.request.data['uuid'])

不幸的是,这会引发错误。我的解决方法是这样的:

def perform_create(self, serializer):
    restaurant = Restaurant.objects.get(restaurant__uuid=self.kwargs['uuid'])
    serializer.save(restaurant=restaurant)

但这显然性能不好,因为它需要做一个额外的查询集。有没有办法让它在 serializer.save() 中一步到位?

编辑

应要求我添加了餐厅模型:

class Restaurant(models.Model):
    name = models.Charfield(max_length=255)
    uuid = models.UUIDField(
        default=uuid.uuid4,
        editable=False,
        unique=True
    )
    owner = models.ForeignkeyField(
        Owner,
        on_delete=models.CASCADE
    )

class Chef(models.Model):
    restaurant = models.ForeignKey(
        Restaurant,
        on_delete=models.CASCADE
    )
    training = models.Charfield(max_length=255)

澄清一下,我想为厨师调用 serializer.save(),根据 UUID 动态地为他提供餐厅。

【问题讨论】:

  • 添加您的 Restaurant 型号代码 sn-p。 restaurantRestaurant 模型本身的外键属性?
  • @ritesh-agrawal 感谢您的帮助。我编辑了帖子以进行澄清。
  • 那么,您是在尝试实现ChefSerializer 还是RestaurantSerializer?是 ChefSeralizer 吗?您正在尝试检索和更新相关的 Restaurant 对象。
  • @ boris-burkov 不,序列化程序已经完成。 (也许可以使用序列化程序。)我要做的是在视图中调用serializer.save() ,并将数据作为参数提供给serializer.save() 方法。简单地说,我想通过将餐厅数据作为参数传递给保存函数来创建一个在餐厅工作的 Chef 对象。
  • 我认为至少需要主键才能直接在Chef 模型实例中创建条目。默认情况下,PrimaryKeyRelatedField 用于序列化程序中的外键。还有一个字段SlugRelatedField,它允许使用特定字段表示目标。但请确保它保存了额外的查询,因为默认情况下,序列化程序查询检查对象是否存在。不过你可以尝试一下。

标签: python django django-rest-framework django-queryset django-serializer


【解决方案1】:

尝试使用单个下划线。

def perform_create(self, serializer):
    serializer.save(restaurant_uuid=self.request.data['uuid'])

【讨论】:

    猜你喜欢
    • 2019-05-12
    • 2013-02-03
    • 2022-01-19
    • 1970-01-01
    • 2020-01-04
    • 2016-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多