Reputation: 79
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
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 django-2.2, 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 theUser
model [Django-doc] directly. For more information you can see the referencing theUser
model section of the documentation.
Upvotes: 1