Problems with dictsort and *_set.count in template

Context

I have these two models:

class Country(models.Model):                                                           
  name = models.CharField(max_length=128, unique=True, validators=[validators.labelvalue])

class City(models.Model):
  name = models.CharField(max_length=128, unique=True, validators=[validators.labelvalue])
  country = models.ForeignKey('myapp.Country', on_delete=models.CASCADE)

If I’m not mistaken, according to the docs country.city_set would automatically exist, and country.city_set.count() will return the number of cities belonging to that country.

related_name is not used in any of those models.

My problem

Now, in a template, I’m trying to loop through the countries, and I would like them sorted by number of cities. So, this is what I do (simplified):

views.py

from django.views.generic import ListView

class CountryList(ListView):
  queryset = models.Country.objects.prefetch_related(
    "city_set",
  )

template.html

{% for country in country_list|dictsort:"city_set.count" %}

However, is not working and just renders a blank page. If I replace city_set.count with name, it works fine, so I guess the problem must be using city_set.count.

What could be issue? Thanks in advance.

From the docs for dictsort:

Takes a list of dictionaries and returns that list sorted by the key given in the argument.

city_set.count is not an attribute in the Country object. The key would need to be city_set. (count would be an attribute in the city_set object.)

You could add an annotation to your query to add the count of city_set as an attribute of the elements in the queryset, and reference it in your dictsort filter.

You could add an annotation to your query to add the count of city_set as an attribute of the elements in the queryset

I have modified the query in this way:

class CountryList(ListView):
  queryset = models.Country.objects.prefetch_related(
    "city_set",
  ).annotate(Count("city_set"))

But now I get the following error:

django.core.exceptions.FieldError: Cannot resolve keyword 'city_set' into field.
Choices are: id, name, city

I could not annotate a count on the city_set field. Instead, I needed to use a city field.
This fixed it:

views.py

class CountryList(ListView):
  queryset = models.Country.objects.prefetch_related(
    "city_set",
  ).annotate(num_cities=Count("city"))

template.html

{% for country in country_list|dictsort:"num_cities" %}

Thanks @KenWhitesell.