0

My Profile model have two m2m fields in one model - region and country. And as you know, country has there own region with foreignkey.

I want to try counting profiles per region - not only include region but also in country__region.

i.e.) If some have only has Africa region, and other has only Congo country (with the region Africa), I want to filter them at one.

I try to solve it using annotate. I can find count of region individually like below

    profiles = Profile.objects.all()
    region_count = profiles.values('region').annotate(region_count=Count('region'))
    country_count = profiles.values('region').annotate(region_count=Count('country__region'))

But how can I count queryset with specific region, filtering with region and region__country at once? Is there any possible method?

Here's my profile / country model. The region model just has name field.

class Profile(models.Model):
    region = models.ManyToManyField(
        Region,
        verbose_name="Region(s) of interest",
        blank=True,
    )
    country = models.ManyToManyField(
        Country,
        related_name="country",
        verbose_name="Countries of interest",
        blank=True,
    )
    ...

class Country(models.Model):
    region = models.ForeignKey(
        Region,
        null=True,
        blank=True,
    )
    ...

Thanks for any help.

Summary

I want to count queryset with region and country__region at once with annotate.

4
  • what version django do you use? Commented Jul 11, 2018 at 9:07
  • is this works ? ( I don't really understand your problem ) region_count = profiles.values('region').annotate(Count('region'), Count('country__region')).distinct() Commented Jul 11, 2018 at 9:16
  • @BearBrown I use 1.11 Commented Jul 11, 2018 at 9:20
  • @AlexisdeCorbier That can't merge region and country__region. My problem detail - I want to get all profiles including region or country__region per region. i.e.) africa - profiles having africa region and having africa in country__region both. Commented Jul 11, 2018 at 9:23

1 Answer 1

1

you can try use conditional-expressions before count:

from django.db.models import Case, When, F, Count

Profile.objects.annotate(
    reg=Case(
        When(region__isnull=True, then=F('country__region')),
        default=F('region'))
    ).values('reg').annotate(region_count=Count('reg'))
Sign up to request clarification or add additional context in comments.

3 Comments

@seuling does it help you, or i wrong in understand your question.
I tried your answer, and it's good to know Case and When. Unfortunately, I guess it's not what I want to find. If use conditional expressions, one profile object is counted just one time. For example, if someone has Africa region and South Korea country, he/she should be counted in both Africa and Asia. But in case-when scenario, it's only counted for Africa.
Anyway, really thanks for your helpful answer. I'm trying to select query with conditional expression

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.