Reputation: 2206
Let us say in my models for a django app, I have three models, each with many to many relationship (this is a toy example).
class User(models.Model):
permissions_group = models.ManyToManyField(Group)
class Group(models.Model):
permissions_area = models.ManyToManyField(Area)
class Area(models.Model):
#other irrelevant field data...
pass
I would like to have a field on my User
model, that expressed the relationship between users and Areas, which is an implicit many-to-many model (that is to say I don't define additional relations which create additional tables in the database, I use the relationship which goes through groups).
I have considered using a custom manager, but that doesn't seem to allow the kind of relationship filtering that one sees with a standard RelatedField manager; I could simply set a decorated property on the class:
class User(models.Model):
@property
permissions_areas(self):
return Area.objects.filter(group__in=self.permissions_groups.all())
But that seems clunky, and doesn't use any django conventions. Is there a conventional way to do this in django using Django's tooling (custom managers or something similar to RelatedManager
) which I am missing?
Upvotes: 1
Views: 219
Reputation: 476669
You can just use two underscores to look through a relation, so:
class User(models.Model):
@property
permissions_areas(self):
return Area.objects.filter(group__user=self).distinct()
The .distinct()
is useful if a User
can belong to multiple groups that have access to this area. Without .distinct()
it would return that Area
for each group that has permission to that area and where the user belongs to.
Upvotes: 1