Django — как реализовать модерацию объекта?

Кажется в директе есть пример такого кейса.
Пользователь создает объявление, отправляет на модерацию, модератор принимает, оно начинает показываться.
Далее пользователь решил что-то подправить, например тест объявления. Отредактировал и отправил на модерацию. Причем, старый вариант по прежнему показывается в поиске, а новый на модерации.

Т.е. где-то храниться информация об обьекте, а где-то о его отредактированной копии, которая на модерации.
Как это лучше реализовать?
Через две независимых модели? Через наследование моделей? Может с одной моделью, добавив какой-то атрибут. Тогда копии будут храниться втой же таблице. Может еще какие варианты есть?

Вариант 1: Одна таблица

class Banner(models.Model):
    name = models.CharField()
    text = models.CharField()
    image = models.ImageField()
    original = models.ForeignKey('self')  # если не None, значит это копия
    moderation_status = modes.IntegerField()


Вариант 2: две независимых модели

class Banner(models.Model):
    name = models.CharField()
    text = models.CharField()
    image = models.ImageField()

class ModerationBanner(models.Model):
    name = models.CharField()
    text = models.CharField()
    image = models.ImageField()
    moderation_status = modes.IntegerField()


Вариант 3: Наследование

class BaseBanner(models.Model):
    name = models.CharField()
    text = models.CharField()
    image = models.ImageField()

class Banner(BaseBanner):
   pass

class ModerationBanner(BaseBanner):
   original = models.ForeignKey(Banner) 
   moderation_status = modes.IntegerField()


Если вы решали подобную задачу, то какой вариант использовали?
  • Вопрос задан
  • 869 просмотров
Решения вопроса 3
@van2048
Как вариант - хранить несколько версий объявления. Показывать в поиске последнюю промодерированную (например по временной метке). Остальные может быть тяжело сопровождать в будущем.

MODERATION_STATUS_CHOICES = (
        (0, _('Not moderated')),
        (1, _('moderated')),
    )

class Banner(models.Model):
    user = models.ForeignKey(User, related_name='banner_user') # в зависимости от случая объявление можно привязать к другой сущности
    #место для других полей, которые не меняются для объявления

class BannerDetail(models.Model):
    banner = models.ForeignKey(Banner, related_name='bannerdetail_banner')
    name = models.CharField()
    text = models.CharField()
    image = models.ImageField()
    moderation_status = modes.IntegerField(choices=MODERATION_STATUS_CHOICES, default=0)
    time_stamp = models.DateTimeField(auto_now=True)
Ответ написан
Комментировать
arblog
@arblog
Решал подобную задачу немного другим образом.

- Есть модель объекта, например Banner.

- Есть дополнительная модель, которая содержит список изменений, которые хотят применить к объекту, например BannerChanges.

1. До модерации отображается объект, например banner01.

2. При внесении изменений, которые требуют модерации, создаётся объект со списком изменений, например banner_changes_01 (список изменений представляет из себя json вида "поле": "новое значение").

3. До принятия решения по модерации система работает с изначальным объектом banner01.

4. В случае успешной модерации к banner01 применяется набор изменений banner_changes_01.

Вокруг это всего можно накрутить историю применения изменений, автора изменений, принявшего решения модератора и возможность отмены изменений.
Ответ написан
sim3x
@sim3x
moderation_status = (..., 
     (999, 'Ревизия для показа') )

Banner:
    name
    text
    image
    moderation_status


Тут много зависит от юзкейса - если у тебя менеджеры не используют агрегацию по истории (по всем историям баннеров), то может ее стоит помеcтить в json поле - менять то ее вообще нестоит, кроме как дописывать
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы