# Clear data-model layer in Django MVC

I have a Django model User

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

def make_viewed(self):
if self.viewed:
return
self.viewed = True
self.save()


So I think that order methods in model is bad idea and actually it's anti-pattern, so next one solution was like this:

class Notification(TimeStampedModel):
user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('user'),
_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.save(commit=False)
self.save()


It looks better, but we have a couple of problems:

1) Model have methods yet
2) Property care side-effect, it doesn't obviously
3) That action require access to instance, so we can't move it to custom field.

• Am I right in thinking that, using the second approach, you can notification.viewed = False and it will set notification._viewed to True and remove a not_viewed_notifications from the user? – Mathias Ettinger Jan 31 '18 at 13:58
• sry, but it's just an example, I can change logic for you if you got a fit of epilepsy. – Denny Feb 1 '18 at 16:54

I would go with a third approach so you don't have to manually update your User model:

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

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

class User(DjangoUser):
@property

1. You don't need special logic in Notification and handle it in your view very simply (you can also have your users "unsee" some notifications);
This approach also have the advantage of not requiring anything from the selected User model (settings.AUTH_USER_MODEL). If using the proposed one, you will have access to the "not viewed" count from the property, if using the base User model from Django (or any other, for that matter), nothing will break and you'll still have access to the reverse relationship. Whereas, in your current implementation, you'll get into troubles when trying to access a non-existent not_viewed_notifications.