Очистить данные-уровень модели в Django шаблона MVC


У меня есть модель пользователя Django

class Notification(TimeStampedModel):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('user'),
                             related_name='notifications')
    viewed = models.BooleanField(verbose_name=_('has viewed'), default=False)

    def make_viewed(self):
            if self.viewed:
                return
            self.viewed = True
            User.objects.filter(id=self.user.id).update(not_viewed_notifications=F('not_viewed_notifications') - Value(1))
            self.save()


Поэтому я считаю, что методы заказа в модели-это плохая идея и на самом деле это анти-паттерн, так что следующий выход был такой:

class Notification(TimeStampedModel):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('user'),
                             related_name='notifications')
    _viewed = models.BooleanField(verbose_name=_('has viewed'), default=False)

    @property
    def viewed(self):
        return self._viewed

    @viewed.setter
    def viewed(self, value):
        if self._viewed:
            return

        self._viewed = True
        self.user.not_viewed_notifications = F('not_viewed_notifications') - Value(1)
        self.user.save(commit=False)
        self.save()


Это выглядит лучше, но у нас есть пара проблем:

1) Модель есть способы еще
2) побочным эффектом имущество по уходу, это не очевидно
3) действия, которые требуют доступ к примеру, поэтому мы не можем переместить его в поле.

О чем ты думаешь?



120
1
задан 31 января 2018 в 11:01 Источник Поделиться
Комментарии
1 ответ

Я бы с третьего подхода, поэтому вам не придется вручную обновлять User модель:

class Notification(TimeStampedModel):
user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('user'),
related_name='notifications')
viewed = models.BooleanField(verbose_name=_('has viewed'), default=False)

from django.contrib.auth.models import User as DjangoUser

class User(DjangoUser):
@property
def not_viewed_notifications(self):
return self.notifications.filter(viewed=False).count()

Это носит двоякий характер:


  1. Вам не нужна особая логика Notification и справиться с этим на ваш взгляд очень просто (вы также можете иметь ваши пользователи "развидеть" некоторые уведомления);

  2. Вы никогда не можете быть синхронизированы между количеством не видно уведомлений для пользователя и состояние уведомления для пользователей.

Этот подход также имеет преимущество не требовать ничего от выбранного User модель (settings.AUTH_USER_MODEL). Если с помощью предложенных один, вы будете иметь доступ к "не просматривается" графа от отеля, если использовать базу пользователей модель с Django (или любой другой, если на то пошло), ничего не сломается, и вы будете по-прежнему иметь доступ к обратной связи. Принимая во внимание, что в текущей реализации, вы получите в неприятности, когда пытается получить доступ к несуществующей not_viewed_notifications.

1
ответ дан 31 января 2018 в 02:01 Источник Поделиться