【问题标题】:Django Rest Framework - how to handle update of an item with order fieldDjango Rest Framework - 如何处理带有订单字段的项目更新
【发布时间】:2020-04-25 12:17:51
【问题描述】:

在我的 DRF 应用中,我有这个模型:

class Item(models.Model):
    label = models.TextField()
    category = models.CharField()
    order = models.IntegerField()
    class Meta:
        ordering = ['order']
        unique_together = ['order', 'category ']

我正在寻找一种更新实例的方法,可能会更改他的订单值,并保持排序顺序正确。

目前,由于 unique_together,序列化程序验证失败。但我不想在检查数据是否正确之前更新我的数据库......

关于如何做到这一点的任何想法? 非常感谢 斯旺

【问题讨论】:

  • 您希望用户能够移动一个项目,然后增加/减少需要在 1 个查询中更改的所有其他行?
  • 是的,但它可能在超过 1 个查询中。
  • 首先你需要在你的序列化器stackoverflow.com/a/46022282/548562禁用验证
  • 我刚刚这样做了,但现在我不知道如何编写保存关闭,到目前为止我尝试的任何更新都在 unicity 上惨遭失败。
  • 您介意订单中有“空白”吗? (1,2,4,5)?

标签: python django django-rest-framework


【解决方案1】:

首先,您需要禁用序列化程序上的 unique_together 验证器,以按照此答案 https://stackoverflow.com/a/46022282/548562 进行验证

class ExampleSerializer(serializers.ModelSerializer):
    def get_unique_together_validators(self):
        """Overriding method to disable unique together checks"""
        return []

然后您可以覆盖update 方法来执行您的重新排序。不过,这会在顺序上留下空白

def update(self, instance, validated_data):
    instance.label = validated_data.get('label', instance.label)
    instance.category = validated_data.get('category', instance.category)
    instance.order = validated_data.get('order', instance.order)
    if Item.objects.exclude(pk=instance.pk, category=instance.category, order=instance.order).exists():
        # If an item already exists with the same order and category shift all
        # Items up by 1 before saving
        Item.objects.filter(category=instance.category, order__gte=instance.order).order_by('-order').update(order=F('order') + 1)
    instance.save()
    return instance

如果您不想要间隙,那么它会变得有点复杂,因为Item 可以更改类别,您需要将旧类别中的项目向下移动。如果一个项目保持在同一类别但它的订单增加了,您可能希望将所有项目之间的所有项目向下移动

【讨论】:

  • 我刚刚尝试了您的解决方案,但更新失败:MySQLdb._exceptions.IntegrityError: (1062, "Duplicate entry '3-2' for key ...")
  • 我尝试过使用 order 子句,但结果相同: Item.objects.filter(category=instance.category, order__gte=instance.order).update(order=F('order') + 1).order_by('-order')
  • 我在发帖后看到了我的错误(我没有复制过去并且放错了order_by)。 Item.objects.filter(category=instance.category, order__gte=instance.order).order_by('-order').update(order=F('order') + 1) 仍然发送异常IntegrityError
  • 好像django顺便不使用order_by子句...
猜你喜欢
  • 2015-09-19
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-04
  • 2017-05-11
  • 2021-04-03
相关资源
最近更新 更多