2010-12-15 62 views
6

Disons que j'ai un modèleDjango recherche plusieurs filtres

models.py

class user: 
    name = models.CharField(max_length=25) 

class job: 
    job_name = models.CharField(max_length=25) 

class user_job: 
    user = models.ForeignKey('user') 
    job = models.ForeignKey('job') 

forms.py

jobs = (
    ('0', 'a'), 
    ('1', 'b'), 
    ('2', 'c'), 
) 

class searchForm: 
    box = forms.ModelMultipleChoiceField(
              choices = jobs, 
              widget = forms.CheckboxSelectMultiple(), 
              label = 'Search', 
             ) 

Je peux rechercher des utilisateurs qui ont l'emploi ' a 'avec

user_job.objects.filter(job__exact = 'a') ... 

J'ai essayé de rechercher des utilisateurs qui ont à la fois l'emploi « a » et emploi « c » comme si

search_q = user_job.objects.filter(job__exact = 'a') 
search_q = search_q.filter(job__exact = 'c') 

mais je reçois tous les utilisateurs qui ont l'emploi « a » ou travail « c », et j'ai besoin de tous les utilisateurs qui ont les deux emplois.

Y a-t-il un moyen de le filtrer via Django, ou ai-je besoin de filtrer sur un travail, puis parcourir les résultats et vérifier le 2ème job?

Répondre

9

Vous trouverez probablement plus facile de faire une recherche à partir du modèle User puisque vous voulez une liste de Users s qui ont les deux emplois. Django configure automatiquement les propriétés de vos modèles qui vous permettent d'accéder aux modèles associés à la fois à partir des instances de modèle et des requêtes de base de données.

En supposant que vous configurez vos modèles comme ceci:

from django.db import models 

class User(models.Model): 
    name = models.CharField(max_length=25) 

    def __repr__(self): 
     return '<User: %s>' % self.name 

class Job(models.Model): 
    name = models.CharField(max_length=25) 

    def __repr__(self): 
     return '<Job: %s>' % self.name 

class UserJob(models.Model): 
    user = models.ForeignKey(User) 
    job = models.ForeignKey(Job) 

    def __repr__(self): 
     return '<UserJob: %s %s>' % (self.user.name, self.job.name) 

et le remplir comme suit:

u1 = User.objects.create(name='u1') 
u2 = User.objects.create(name='u2') 
u3 = User.objects.create(name='u3') 

a = Job.objects.create(name='a') 
b = Job.objects.create(name='b') 
c = Job.objects.create(name='c') 

UserJob.objects.create(user=u1, job=a) 
UserJob.objects.create(user=u2, job=a) 
UserJob.objects.create(user=u2, job=b) 
UserJob.objects.create(user=u3, job=a) 
UserJob.objects.create(user=u3, job=c) 

La requête suivante vous renvoie l'utilisateur 3, qui est le seul utilisateur qui a à la fois « un emploi » et « Job c »:

u = User.objects.filter(userjob__job=a).filter(userjob__job=c) 

(ou, si vous préférez de se référer aux emplois par nom plutôt que J ob par exemple):

u = User.objects.filter(userjob__job__name='a').filter(userjob__job__name='c') 

Vous pouvez voir comment Django vous permet de parcourir les champs liés du modèle User au modèle UserJob avec la double notation underscore (Django docs sur ce sont ici: http://docs.djangoproject.com/en/1.2/topics/db/queries/#lookups-that-span-relationships.

Une fois que vous revenez l'objet User, vous pouvez accéder de façon similaire aux instances de UserJob en utilisant les propriétés de la relation que Django ajoute au modèle:

u = User.objects.filter(userjob__job__name='a').filter(userjob__job__name='c') 
jobs = u.userjob_set.all() 
+0

hmm, cela fonctionne, je comprends DonT bien comment, mais juste fonctionne: D ... pourquoi est-ce que je regarde dans User.objects.filter? et pas dans UserJob.objects.filter? Si vous le pouvez ... pouvez-vous me donner un peu de sql de comment cela va ressembler ... de toute façon c'est souvent ce dont j'avais besoin ... Merci pour votre temps et GL – void

+0

Vous filtrez l'utilisateur 'objet parce que ce que vous voulez en arrière est une liste d'utilisateurs (ceci basé sur le fait que la question de domaine de problème est" Quels utilisateurs ont le travail a et le travail c? "). Il est également sémantiquement plus facile de formuler une requête django saine pour ce problème en commençant par l'objet 'User'. Vous pouvez voir les instructions SQL générées par django en examinant les résultats de 'django.db.connection':' depuis la connexion d'importation django.db; print connection.queries' –