Django Rest Framework - как обработать обновление элемента с полем заказа - PullRequest
0 голосов
/ 08 января 2020

В моем приложении DRF у меня есть эта модель:

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

Я ищу способ обновить экземпляр, возможно, изменить его значение заказа и сохранить правильную последовательность заказа.

В настоящее время проверка сериализатора не удалась из-за unique_together. Но я не хочу обновлять свою БД, прежде чем проверять корректность данных ...

Есть идеи, как это сделать? Большое спасибо Swann

1 Ответ

0 голосов
/ 08 января 2020

Сначала вам нужно отключить валидатор unique_together в сериализаторе, чтобы пройти валидацию согласно этому ответу { ссылка }

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 может изменить категорию, вам нужно переместить элементы в старом категория вниз. Если предмет остается в той же категории, но его порядок увеличен, вы можете переместить все предметы между ними вниз

...