J'ai un modèle d'utilisateur avec les champs ci-dessous.

class User(models.Model):
    user_id = models.CharField(max_length=40,unique=True)
    user_name = models.CharField(max_length=40)
    user_email = models.EmailField()
    user_city = models.CharField(max_length=40)
    class Meta:
        ordering = ['user_id']
        verbose_name = 'User MetaData'
        verbose_name_plural = 'Users MetaData'
    def __unicode__(self):
        return self.user_id

Maintenant, je veux filtrer les 10 principales villes par utilisateur, c'est-à-dire la liste des 10 meilleures villes avec le nombre d'utilisateurs dans cette ville. J'ai utilisé la syntaxe ci-dessous mais j'obtiens toujours city_count = 1 ..

User.objects.annotate(city_count=models.Count('user_city')) .order_by('-city_count'))[:10]

J'ai également essayé la syntaxe ci-dessous mais même résultat ...

User.objects.values('user_city').annotate(city_count=models.Count('user_id')) .order_by('-city_count'))[:10]

Où je me trompe?

1
Naresh 21 juil. 2015 à 17:46

2 réponses

Meilleure réponse

Votre deuxième exemple est juste, corrigez simplement les fautes de frappe. Remplacer

User.objects.values('user_city').annotate(city_count=models.Count('user_id')) .order_by('-city_count'))[:10]

Avec

User.objects.values('user_city').annotate(city_count=models.Count('user_city')).order_by('-city_count')[:10]

MISE À JOUR 1, 2:

top_cities_queryset = (User.objects
                       .values('user_city')
                       .annotate(user_city_count=models.Count('user_city'))
                       .order_by('-user_city_count')
                       .values_list('user_city', 'user_city_count'))

top_cities = [{city: count} for city, count in top_cities_queryset]
1
f43d65 22 juil. 2015 à 07:14

Je ne pense pas que vous puissiez faire cela sans un modèle qui a une relation avec User. En gros, vous devez exécuter la requête sur un autre modèle, puis annoter le user_city de cet autre modèle. C'est un peu bizarre pour votre cas spécifique.

Cependant, vous pouvez le faire en Python. Voici comment je le ferais:

from collections import Counter
city_counter = Counter(User.objects.values_list('user_city', flat=True))
top_ten_cities_and_counts = city_counter.most_common()[:10]
top_ten_cities = [city for city, count in top_ten_cities_and_counts]
2
schillingt 21 juil. 2015 à 15:10