1

Example:

class MyUser(models.Model):
    blocked_users = models.ManyToManyField("self", blank=True, null=True)

user = MyUser.object.get(pk=1)
user.blocked_users.add(user)
user.blocked_users.all()[0] == user # (!!!)

Can It be prevented on model/db level? Or we need just do check somewhere in app.

alexche8
  • 1,270
  • 3
  • 19
  • 26

1 Answers1

3

Looking at the Django docs for ManyToManyField arguments, it does not seem possible.

The closest argument to what you want is the limit_choices_to However, that only limits choices on ModelForms and admin (you can still save it like you did in your example), and there is currently no easy way to use it to limit based on another value (pk) in the current model.

If you want to prevent it from happening altogether, you'll have to resort to overriding the save method on the through model--something like:

class MyUser(models.Model):
    blocked_users = models.ManyToManyField(..., through="BlockedUser")

class BlockedUser(models.Model):
    user = models.ForeignKey(MyUser)
    blocked = models.ForeignKey(MyUser)

    def save(self, *args, **kwargs):
        # Only allow this relationship to be created if 
        if self.user != self.blocked:
            super(BlockedUser, self).save(*args, **kwargs)

You could of course also do this with signals.

Community
  • 1
  • 1
pcoronel
  • 3,833
  • 22
  • 25