karlrez
karlrez

Reputation: 79

Overriding init method of Django model

What I am trying to do is implement a 'follower system' for my app and I just want to make sure a user can't be followed multiple times by the same user. I can't seem to implement this as the admin continues to let me create duplicate relationships.

models.py

     class FollowRelationshipManager(models.Manager):
        def create_followrelationship(self, follower, followee, date):
            if FollowRelationship.objects.filter(
                follower=follower,
                followee=followee
                ).exists():
                    raise ValueError('User is already followed')
            else:
                followrelationship = self.create(
                    follower=follower,
                    followee=followee,
                    date=date
                )
                return followrelationship
    
    
    class FollowRelationship(models.Model):
        follower = models.ForeignKey(User, related_name='follower', on_delete=models.CASCADE)
        followee = models.ForeignKey(User, related_name='followee', on_delete=models.CASCADE)
        date = models.DateTimeField(auto_now_add=True)

Upvotes: 1

Views: 168

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477608

You can simply make use of a UniqueConstraint [Django-doc] which will prevent that the combination of the two (or more) fields:

class FollowRelationship(models.Model):
    follower = models.ForeignKey(
        User,
        related_name='follower',
        on_delete=models.CASCADE
    )
    followee = models.ForeignKey(
        User,
        related_name='followee',
        on_delete=models.CASCADE
    )
    date = models.DateTimeField(auto_now_add=True)

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=['follower', 'followee'],
                name='follow_once'
            )
        ]

This will also be enforced at the database level.

Prior to , you can use unique_together [Django-doc]:

# prior to Django-2.2

class FollowRelationship(models.Model):
    follower = models.ForeignKey(
        User,
        related_name='follower',
        on_delete=models.CASCADE
    )
    followee = models.ForeignKey(
        User,
        related_name='followee',
        on_delete=models.CASCADE
    )
    date = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = [['follower', 'followee']]

Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

Upvotes: 1

Related Questions