petr
petr

Reputation: 2586

Determining "reachable" objects linked via many-to-many relations

My model is setup with many-to-many relationships to separate items into groups and categories:

class DownloadableResourceGroup(models.Model):
    pass

class DownloadableResourceCategory(models.Model):
    pass

class DownloadableResource(models.Model):    
    res_categories = models.ManyToManyField(DownloadableResourceCategory, blank=True)
    res_groups     = models.ManyToManyField(DownloadableResourceGroup, blank=True

Each view has a resource group assigned to it, which provides initial filtering of the resources. Then, I would like to apply further filters based on categories. My question is - how do I get list of DownloadableResourceCategories from DownloadableResources filtered by a DownloadableResourceGroup without iterating over them? I only want to show categories present on the DownloadableResources that are in the current view and do not want to show categories that do not have any items in them.

To further illustrate what I am doing:

# fetch relevant DownloadableResources
items = active_collection.downloadableresource_set.all().order_by("title")

# get only categories present in the items above
relevant_categories = THIS_IS_WHAT_I_AM_AFTER

Upvotes: 0

Views: 30

Answers (1)

AKS
AKS

Reputation: 19831

You can get all the relevant categories as following:

relevant_categories = DownloadableResourceCategory.objects.filter(
                           downloadableresource__in=items).distinct()

Do note the use of distinct() since it is a m2m relationship you can get category multiple times. distinct will only return the unique categories in this case.

Upvotes: 1

Related Questions