简体   繁体   中英

Model field for implicit many-to-many (many-to-many-to-many) relationship in Django

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?

You can just use two underscores to look through a relation, so:

class User(models.Model):

    @property
    permissions_areas(self):
        return Area.objects.filter().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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM