Ad

How Can I Filter Related Field In Django?

- 1 answer

Say I have the model User which has a many-to-many relation with the model Company; and the model UserType, which is connected to both User and Company. Like this:

class User(models.Model):
    name = models.TextField()

class Company(models.Model):
    name = models.TextField()
    users = models.ManyToManyField(User, related_name="companies")

class UserType(models.Model):
    name = models.TextField()
    company = models.ForeignKey(Company, related_name="user_types")
    users = models.ManyToManyField(User, related_name="user_types")

I wanna find all Users in a Company, which is simple enough: User.objects.filter(companies=some_company). However, I also wanna filter the user_types field on the returned users objects, so that only UserType objects connected to the given Company is returned. To explain it with code, this should return true:

def check_user_types(users, company):
    for user in users:
        for user_type in user.user_types:
            if user_type.company != company:
                return false
    return true

How would I do this?

Ad

Answer

I figured it out. For anyone facing the same problem, this solved it:

from django.db.models import Prefetch

users = User.objects.filter(companies=company).prefetch_related(
    Prefetch(
        "user_types",
        queryset=UserType.objects.filter(company=company),
    )
)
Ad
source: stackoverflow.com
Ad