2012-06-26 4 views
4

J'ai des problèmes avec django sur la façon de récupérer des données de la semaine dernière (pas il y a 7 jours). Utiliser date.isocalendar()[1] serait génial. Cependant, certaines recherches sur stackoverflow ne m'ont pas donné de résultats satisfaisants.Comment récupérer des enregistrements des dernières semaines dans django

Quoi que ce soit, je pourrais faire sans portabilité et utiliser la fonction INTERVAL de mysql. C'est la requête que je veux faire en utilisant ORM de django.

SELECT id, user_id, CAST(timestamp AS Date), WEEK(timestamp,3), WEEK(CURDATE(), 3) FROM main_userstats WHERE week(timestamp, 3) = WEEK(DATE_SUB(CURDATE(), INTERVAL 1 WEEK), 3)

comment puis-je faire cela en utilisant la fonction extra dans django (s'il est impossible de le faire d'une autre manière plus simple)?

+0

Je dis juste, cela utilisé pour me frustrer beaucoup dans Django et j'ai eu un choix passer à Ruby, donc je l'ai fait et je n'ai pas regardé en arrière: Au lieu de: 'Entry.objects.filter (pub_date__gte = timezone.now(). date() - timedelta (jours = 7))' Vous écrivez : 'Entry.where (: pub_date.gte => 7.jours. La même syntaxe s'applique aussi bien aux bases de données de type SQL qu'à MongoDB, ce qui est fantastique. – Hackeron

Répondre

17

Je suppose que ce que vous cherchez sont toutes les entrées qui appartiennent à la même semaine civile de la semaine précédente.

Cela devrait faire l'affaire:

class Entry(models.Model): 
    pub_date = models.DateField([...]) 

Pour obtenir les objets:

from datetime import timedelta 
from django.utils import timezone 
some_day_last_week = timezone.now().date() - timedelta(days=7) 
monday_of_last_week = some_day_last_week - timedelta(days=(some_day_last_week.isocalendar()[2] - 1)) 
monday_of_this_week = monday_of_last_week + timedelta(days=7) 
Entry.objects.filter(created_at__gte=monday_of_last_week, created_at__lt=monday_of_this_week) 

Notez que j'ai ajouté 7 jours pour le lundi de la semaine au lieu d'ajouter 6 jours pour obtenir le dimanche de la semaine dernière et que j'ai utilisé created_at__lt = monday_of_this_week (au lieu de __lte =). Je l'ai fait parce que si votre pub_date était un champ DateTimeField, il n'inclurait pas les objets du dimanche puisque l'heure est 00:00:00 lors de l'utilisation de now(). Date().

Cela pourrait facilement être ajusté pour considérer dimanche comme le premier jour de la semaine, mais isocalendar() le considère comme le dernier, donc je suis allé avec ça.

Si vous utilisez Django < 1.4 utiliser les éléments suivants:

from datetime import date, timedelta 
some_day_last_week = date.today() - timedelta(days=7) 

au lieu de:

from datetime import timedelta 
from django.utils import timezone 
some_day_last_week = timezone.now().date() - timedelta(days=7) 
4

Regardez la méthode filter de Django ORM.

exemple de base:

class Entry(models.Model): 
    pub_date = models.DateField([...]) 

Entry.objects.filter(pub_date__year=2006) 

Mais vous pouvez faire des requêtes plus complexes avec filtre comme:

Entry.objects.filter(pub_date__gte=datetime.now()) 

Comme vous pouvez le voir, vous pouvez utiliser datetime et d'autres bibliothèques Python pour définir des dates précises. Regardez la documentation pour field lookups pour voir quelles sont les possibilités que vous avez.

Dans votre cas, vous pouvez faire quelque chose comme ça (inspired by this Stackoverflow post):

from datetime import date, timedelta 

d=date.today()-timedelta(days=7) 
Entry.objects.filter(pub_date__gte=d) 

Je ne suis pas sûr à 100% si cette recherche fonctionne, mais il est la bonne direction.

+0

Merci, je sais comment utiliser la méthode 'filter'. Et je sais aussi que bien que je puisse filtrer par année ou par mois, je ne peux pas filtrer par semaine. Je veux également éviter d'utiliser des plages de dates. – xpanta

+0

Que voulez-vous dire par "semaine"? Voulez-vous simplement dire les 7 derniers jours ou voulez-vous dire la dernière semaine du calendrier? – Jens

+0

Je veux dire la semaine précédente. C'est pourquoi j'ai aussi mentionné que 'datetime.idocalendar() [1]' serait génial à utiliser. – xpanta

Questions connexes