2009-12-30 11 views
8

Compte tenu des modèles suivants:Django: Filtrage sur l'objet associé, la suppression des doublons du résultat

class Blog(models.Model): 
    name = models.CharField() 

class Entry(models.Model): 
    blog = models.ForeignKey(Blog) 
    content = models.CharField() 

Je cherche à passer ce qui suit à un modèle:

blogs = Blog.objects.filter(entry__content__contains = 'foo') 
result = [(blog, blog.entry_set.filter(content__contains = 'foo')) 
      for blog in blogs] 
render_to_response('my.tmpl', {'result': result} 

Cependant, « Blog .objects.filter (...) "renvoie plusieurs fois le même objet Blog si plusieurs entrées correspondantes sont trouvées.

Comment supprimer les doublons? Ou mieux encore, ai-je manqué un moyen plus simple de passer la liste des correspondances aux modèles? L'ajout de .distinct() vous donnera seulement des résultats distincts.

+2

J'ai essentiellement le même problème (mais plus évident). POURQUOI Y A-T-IL DES DUPLICATEURS EN PREMIER LIEU? Est-ce que 'filter' n'est pas censé RESTREINDRE l'ensemble? Je pense que c'est un bug dans django, n'est-ce pas? C'est un peu comme https://code.djangoproject.com/ticket/12625 – osa

Répondre

14

+0

Un point subtil à noter si vous utilisez distinct avec un nom de champ ex distinct ('field_name'), il ne fonctionnera pas sur mysql et * seulement * fonctionne pour pgsql. src: https://docs.djangoproject.com/fr/1.4/ref/models/querysets/#django.db.models.query.QuerySet.distinct faites défiler jusqu'à "Note". J'ai juste cogné ma tête dessus pendant une heure, maintenant je pense que je devrais avoir lu le document clairement. :) –

6

Voir la QuerySet API Docs pour la fonction "distincte()":

Renvoie un nouveau QuerySet qui utilise SELECT DISTINCT dans sa requête SQL. Cette élimine les lignes en double des résultats de la requête .

Par défaut, un QuerySet ne supprimera pas les lignes dupliquées. En pratique, ceci est rarement un problème, car des requêtes simples telles que Blog.objects.all() n'introduisent pas la possibilité de dupliquer les lignes de résultats. Toutefois, si votre requête couvre plusieurs tables , il est possible d'obtenir des résultats en double lorsqu'un QuerySet est évalué. C'est à ce moment que vous utiliseriez distinct().