2009-08-18 5 views
1

I ont les 2 modèles suivants:Est-il possible de filtrer sur un élément associé dans les annotations Django?

class Job(models.Model): 
    title = models.CharField(_('title'), max_length=50) 
    description = models.TextField(_('description')) 
    category = models.ForeignKey(JobCategory, related_name='jobs') 
    created_date = models.DateTimeField(auto_now_add=True) 

class JobCategory(models.Model): 
    title = models.CharField(_('title'), max_length=50) 
    slug = models.SlugField(_('slug')) 

Voici où je suis à la requête jusqu'ici:

def job_categories(): 
    categories = JobCategory.objects.annotate(num_postings=Count('jobs')) 
    return {'categories': categories} 

Le problème est que je ne veux que compter les emplois qui ont été créés dans le 30 derniers jours. Je souhaite toutefois renvoyer toutes les catégories, et pas seulement les catégories qui ont des emplois qualifiés.

Répondre

1

J'ai décidé d'aborder cette question différemment et j'ai choisi de ne pas utiliser d'annotations du tout. J'ai ajouté un gestionnaire au modèle Job qui renvoyait uniquement les travaux actifs (30 jours ou moins) et créait une propriété sur le modèle JobCategory qui demandait le nombre de travaux de l'instance. Mon templatetag a simplement renvoyé toutes les catégories. Voici le code pertinent.

class JobCategory(models.Model): 
    title = models.CharField(_('title'), max_length=50, help_text=_("Max 50 chars. Required.")) 
    slug = models.SlugField(_('slug'), help_text=_("Only letters, numbers, or hyphens. Required.")) 

    class Meta: 
     verbose_name = _('job category') 
     verbose_name_plural = _('job categories') 

    def __unicode__(self): 
     return self.title 

    def get_absolute_url(self): 
     return reverse('djobs_category_jobs', args=[self.slug]) 

    @property 
    def active_job_count(self): 
     return len(Job.active.filter(category=self)) 

class ActiveJobManager(models.Manager): 
    def get_query_set(self): 
     return super(ActiveJobManager, self).get_query_set().filter(created_date__gte=datetime.datetime.now() - datetime.timedelta(days=30)) 

class Job(models.Model): 
    title = models.CharField(_('title'), max_length=50, help_text=_("Max 50 chars. Required.")) 
    description = models.TextField(_('description'), help_text=_("Required.")) 
    category = models.ForeignKey(JobCategory, related_name='jobs') 
    employment_type = models.CharField(_('employment type'), max_length=5, choices=EMPLOYMENT_TYPE_CHOICES, help_text=_("Required.")) 
    employment_level = models.CharField(_('employment level'), max_length=5, choices=EMPLOYMENT_LEVEL_CHOICES, help_text=_("Required.")) 
    employer = models.ForeignKey(Employer) 
    location = models.ForeignKey(Location) 
    contact = models.ForeignKey(Contact) 
    allow_applications = models.BooleanField(_('allow applications')) 
    created_date = models.DateTimeField(auto_now_add=True) 

    objects = models.Manager() 
    active = ActiveJobManager() 

    class Meta: 
     verbose_name = _('job') 
     verbose_name_plural = _('jobs') 

    def __unicode__(self): 
     return '%s at %s' % (self.title, self.employer.name) 

et l'étiquette ...

def job_categories(): 
    categories = JobCategory.objects.all() 
    return {'categories': categories} 
4

Juste une supposition ... mais cela fonctionnerait-il?

def job_categories(): 
    thritydaysago = datetime.datetime.now() - datetime.timedelta(days=30) 
    categories = JobCategory.objects.filter(job__created_date__gte=thritydaysago).annotate(num_postings=Count('jobs')) 
    return {'categories': categories} 

Voir "lookups-that-span-relationships" pour plus de détails sur les requêtes couvrants. Hmmm ... probablement besoin d'une autre requête là-dedans pour obtenir toutes les catégories ...

+1

Cela renverra uniquement les catégories qui ont des emplois créés au cours des 30 derniers jours. J'essaie également d'éviter de renvoyer plusieurs jeux de requête, car cela va à l'encontre du but de l'utilisation des annotations. Cette fonction existe réellement sous forme de template, et j'espérais, au niveau de la couche de template, inclure les count avec chacune des catégories (même si le compte est 0). Merci quand même. – gsiegman

+0

Oui, je pense que vous allez devoir effectuer deux requêtes. – monkut

Questions connexes