Skip to content
Advertisement

Django: How do I get referenced objects in a symmetric ManyToMany relationship?

I’ve created a Many-to-Many relationship for the model UserProfile, to enable users to grant access to a particular feature to one another. The relationship works as expected with the use of symmetrical=False to ensure a user access is one-way.

Model

from django.contrib.auth.models import User

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    phone = models.IntegerField(blank=True, null=True)
    image = models.ImageField(upload_to='profile_image', default="default_thumbnail.jpg")
    department = models.ForeignKey(DepartmentModel, on_delete=models.SET_NULL, null=True)
    allow_booking_access = models.ManyToManyField("self", blank=True, symmetrical=False)

    def __str__(self):
        return self.user.username


class UserInline(admin.StackedInline):
    model = UserProfile
    can_delete = False
    verbose_name_plural = 'UserAccounts'


class UserAccount(BaseUserAdmin):
    inlines = (UserInline,)

I am able to query the users that a particular user wants to grant access to via: (for example id=1)

UserProfile.objects.get(id=1).allow_booking_access.all()

However, I would like to retrieve the users that have granted access to the particular user.

How would I do this?

Additional Information

Using Relation Database Information

Advertisement

Answer

You can filter with:

UserProfile.objects.filter(allow_booking_access=my_user)

With your sample data, it will return the UserProfile with id=7 for this query.

or if you want to query in reverse:

UserProfile.objects.filter(userprofile=my_user)

With your sample data, it will return the UserProfiles with id=7, id=3, user=4 and user=7 for this query.

Advertisement