Below the Radar
Below the Radar

Reputation: 7635

Django - Number of instance in a related ManyToManyField for a given queryset

I would like to know how many maps are related by a ManyToManyField to a queryset, or said differently, how many maps have at least one of the shapefiles as layer.

models.py:

class Map(models.Model):
    layers = models.ManyToManyField(Shapefile)

class Shapefile(models.Model):
    filename = models.CharField(max_length=255)

views.py:

shapefiles = Shapefile.objects.filter(created_by=request.user)
map_instances = Map.objects... ???

example:

shape1 = Shapefile(filename = 'shape1')
shape2 = Shapefile(filename = 'shape2')
shape3 = Shapefile(filename = 'shape3')
map1 = Map(name = 'map1')

map1.layers.add(shape1)
map1.layers.add(shape2)
map1.layers.add(shape3)

shapefiles = Shapefile.objects.all()
map_instance = [shape.map_set.count() for shape in shapefiles]
print map_instance
>>>[1,1,1]
print sum(map_instance)
>>> 3

or alternatively I could do:

map_instance = Map.objects.filter(layers__in=shapefiles)
print map_instance.count()
>>>3

for my needs, the map_instance should return 1 map because there is only one map instance that contains the 3 shapefiles. I just dont get how to make it works...

Upvotes: 1

Views: 105

Answers (2)

frnhr
frnhr

Reputation: 12903

Perhaps this is what you are looking for:

from django.db.models import Count

maps_with_one_or_more_layer = Map.objects.all().annotate(Count('layers')).filter(layers__count__gte=1)

how_many = maps_with_one_or_more_layers.count()

Docs: QuerySet API reference - Annotate

Upvotes: 1

Mihai Zamfir
Mihai Zamfir

Reputation: 2166

map_instances = shapefiles.count()

But to be more in the style of Django you can create a manager for your model:

class ShapefileManager(models.Manager):
    def map_instances(self, user):
        return self.filter(created_by=user).count()

class Shapefile(models.Model):
    filename = models.CharField(max_length=255)

    objects = ShapefileManager()

number = Shapefile.objects.map_instances(request.user)

EDIT: Sorry, missunterstood your question. But I think this link are what you need, it is a simillar issue:

  1. count values from manytomanyfield

  2. How to count and display objects in relation ManyToMany in Django

Upvotes: 0

Related Questions