Python Django Rest框架-如何使用order字段处理项目更新
在我的DRF应用程序中,我有以下型号:Python Django Rest框架-如何使用order字段处理项目更新,python,django,django-rest-framework,Python,Django,Django Rest Framework,在我的DRF应用程序中,我有以下型号: class Item(models.Model): label = models.TextField() category = models.CharField() order = models.IntegerField() class Meta: ordering = ['order'] unique_together = ['order', 'category '] 我正在寻找一种更新实
class Item(models.Model):
label = models.TextField()
category = models.CharField()
order = models.IntegerField()
class Meta:
ordering = ['order']
unique_together = ['order', 'category ']
我正在寻找一种更新实例的方法,可能会更改其顺序值,并保持顺序正确
当前,序列化程序验证失败,因为存在唯一的\u。但我不想在检查数据是否正确之前更新数据库
你知道怎么做吗?
谢谢
Swann首先,您需要禁用序列化程序上的unique_-together验证器,以便根据此答案通过验证 然后您可以覆盖
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
如果您不希望出现间隙,那么它会变得稍微复杂一些,因为
项目
可能会更改类别,您可能希望将旧类别中的项目向下移动。如果某个项目保持在同一类别中,但其顺序增加,则您希望将所有项目向下移动您希望用户能够移动某个项目,然后在一次查询中递增/递减所有需要更改的其他行?是,但它可能存在于多个查询中。首先,您需要禁用serialiser上的验证。我刚刚完成了这项工作,但现在我不知道如何编写“保存关闭”,我之前尝试的任何更新在unicity上都失败得很惨。您介意在顺序中设置“间隙”吗?(1,2,4,5)?我刚刚尝试了您的解决方案,但更新失败:MySQLdb.\u exceptions.IntegrityError:(1062,“key的重复条目'3-2'”)我尝试了order子句,但结果相同:Item.objects.filter(category=instance.category,order\u gte=instance.order).update(order=F('order')+1).order\u by('order'))我在发布后看到了我的错误(我没有抄袭过去的内容,也没有把订单放错地方)。Item.objects.filter(category=instance.category,order\u gte=instance.order).order\u by('-order').update(order=F('order')+1)仍然发送异常integrityError就像django没有使用order\u by子句一样。。。
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