Наложение заказа на связанные (через внешний ключ) объекты - PullRequest
1 голос
/ 19 декабря 2009

Хорошо, представьте типичный сценарий, - есть объект потока и комментарии, прикрепленные к нему. Это можно выразить в терминах django ORM примерно так:

class Thread(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)

class Comment(models.Model):
    id = models.AutoField(primary_key=True)
    content = models.TextField()
    created = models.DateTimeField(editable=False)
    thread = models.ForeignKey(Thread, related_name='comments')

    def save(self, force_insert=False, force_update=False):
        self.created = datetime.datetime.now()
        super(Comment, self).save(force_insert, force_delete)

Таким образом, при отображении фактических данных комментарии будут упорядочены по времени их создания (поскольку я предпочитаю , а не , чтобы предположить, что поле идентичности также гарантирует вам правильный порядок записи).

Но что, если мне нужно было иметь возможность контролировать (и изменять) порядок, в котором комментарии должны появляться в потоке и , чтобы иметь возможность перемещать комментарии из одного потока в другой.

Этого можно достичь, добавив, например, поле «последовательность» к модели комментария и ограничив уникальность комбинации поля «последовательность» и поля «нить» модели комментария (чтобы можно было нет комментариев в потоке с таким же порядковым номером). Уникальный ключ в этих полях должен быть достаточным (с точки зрения django, это может быть выполнено через unique_together, я думаю).

Однако это добавляет вычислительные издержки (и кодирование: P), потому что если вы хотите изменить порядок комментариев, изменив их порядковые номера, вы также должны обновить комментарии с порядковыми номерами, более высокими, чем целевой порядковый номер комментария. И так далее. Это просто напрашивается на неприятности.

Почему-то, я просто не могу обдумать это. Может быть, я просто что-то упустил?

(Если это возможно, не рассматривайте это как проблему, связанную только с django. IMO, это не зависит от языка, поскольку в нем нет ничего специфичного для django, когда вы об этом думаете)

РЕДАКТИРОВАТЬ: Я вдруг понял, что нет фактического вопроса в вопросе. Таким образом, вопрос в том, что было бы самым легким способом реализации такой модели, помимо очевидного способа, который я описал (мне кажется слишком громоздким).

Ответы [ 3 ]

2 голосов
/ 19 декабря 2009

Если вы укажете атрибут ordering для класса комментариев, этот порядок будет соблюдаться везде, где отображаются комментарии.

class Comment(models.Model):
    id = models.AutoField(primary_key=True)
    content = models.TextField()
    created = models.DateTimeField(editable=False)
    thread = models.ForeignKey(Thread, related_name='comments')

    class Meta:
        ordering = ('-created')

    def save(self, force_insert=False, force_update=False):
        self.created = datetime.datetime.now()
        super(Comment, self).save(force_insert, force_delete)

Документы здесь .

Если вы переместите комментарий из потока A в поток B, из-за указанного порядка он все равно будет отображаться в правильном порядке создания ...

Но, может быть, я неправильно понял ваш вопрос ...


Редактировать: ОК, так что ваш вопрос действительно сводится к:

«Но что если бы мне нужно было иметь возможность контролировать (и изменять) порядок, в котором комментарии должны появляться в потоке, и иметь возможность перемещать комментарии из одного потока в другой.»

Я не думаю, что вы найдете какой-то механизм, отличный от того, что вы упомянули: порядковый номер в классе Comment.

И, да, когда вы перемещаете комментарий из цепочки в ветку, вам понадобится некоторая логика, чтобы изменить порядок вещей, если это необходимо.

Если это действительно ваше требование, я не вижу механизмов, облегчающих вашу жизнь - извините.

1 голос
/ 20 декабря 2009

Если я понимаю ваш вопрос (не совсем уверен, что понимаю), вы хотите создать и поддерживать произвольный порядок комментариев относительно темы.

Единственный известный мне способ сделать это - это иметь поле упорядочения в комментарии или поле list-of-Comment-ids-in-order в теме, либо, возможно, отдельную таблицу с (потоком). -id, Comment-id, order) кортеж в нем.

Для веб-сайта, который я сделал около 2 лет назад, мы выбрали средний вариант для информационного бюллетеня, который содержал 10-30 статей. Я использовал магию jQuery на странице администрирования информационного бюллетеня, и это позволило администраторам перетасовывать заголовки статей, в то время как в фоновом режиме оно обновляло поле Article-ids-in-order в информационном бюллетене.

0 голосов
/ 20 декабря 2009

Альтернативный подход заключается в использовании числа с плавающей запятой в качестве поля заказа. Таким образом, если вы хотите поместить комментарий в середину потока, вы просто вычисляете среднее значение предыдущего и следующего комментария и используете его для поля упорядочения вставляемого комментария. Конечно, существует ограничение на то, сколько раз вы можете выполнить деление с плавающей запятой, прежде чем начнете получать одинаковые значения, но это легко можно решить, периодически умножая все поля порядка на 2: * 2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...