Django обновление поля заказа при сохранении

Продвижение по этому вопросу:

Обновление поля порядка списка модели Django

Я пытаюсь обновить все поля заказа, когда я обновляю 1 запись из результата перетаскивания списка.

Текущая реализация с использованием связанного вопроса:

class Section(models.Model):
    name = models.CharField()
    order = models.IntegerField(default=0)

    def save(self, *args, **kwargs):
        existing_sections = (
            Section.objects.filter(
                order__gte=self.order
            )
            .exclude(id=self.id)
            .order_by("order")
        )
        existing_sections.update(order=F("order") + 1)

        super(Section, self).save(*args, **kwargs)

Допустим, у меня есть 5 полей, с порядком полей от 1 до 5 по возрастанию.

Этот код работает нормально, если я добавляю новую секцию в начале или в конце последовательности. Он сделает первый 1 и добавит 1 ко всем существующим.

Но если я хочу перейти от индекса 3 к индексу 5, то в итоге я получу следующий результат. Обратите внимание на порядок = 3 отсутствует и добавлено 6 в конец.

order = 1 
order = 2
order = 4
order = 5
order = 6 

Думаю, вам следует различать вставку и перемещение. Вы знаете, что это перемещение, потому что ваша модель пк не является никакой. При перемещении вы должны только изменить порядок книг между последним местом и новым.

class Section(models.Model):
    name = models.CharField()
    order = models.IntegerField(default=0)

    def save(self, *args, **kwargs):
        is_insert = self.id is not None
        if is_insert:
          # is insert, reorder all
          existing_sections = (
            Section.objects.filter(
                order__gte=self.order
            )
            .exclude(id=self.id)
            .order_by("order")
          )
          existing_sections.update(order=F("order") + 1)
        else:
          # is moving a book
          previous_order = (
            Section
            .objects
            .filter(pk=self.id)
            .values_list('order', flat=true)
            [0])
          Section.objects.filter(
             order_gte=previous_order
          ).filter(
             order_lte=self.order
          ).exclude(id=self.id
          ).update(order=F("order") - 1)

        super(Section, self).save(*args, **kwargs)

Отказ от ответственности: не тестировалось, я просто написал здесь код. Возьмите идею и отладьте процесс

Вернуться на верх