2010-10-09 4 views
0

J'ai un modèle Django, montré ci-dessous, que j'utilise pour garder une trace des adresses IP qui visitent mon site et quand.Django: S'il vous plaît aider avec ce jeu de requête

class Visit(models.Model): 
    created   = models.DateTimeField(default=datetime.utcnow) 
    ip    = models.IPAddressField(editable=False) 

Je voudrais écrire une méthode sur ce modèle qui renvoie le nombre de jours pris pour les 100 dernières visites à partir d'une adresse IP particulière. Les visites multiples en une seule journée (heure, etc.) à partir d'une adresse IP comptent toutes comme des visites séparées. Donc, si quelqu'un visted le site 100 fois au cours des 2 derniers jours, il reviendrait 2, 100 fois au cours des 8 derniers jours, il reviendrait 8, et ainsi de suite.

Répondre

0

Une approche simple consiste à obtenir les 100 derniers objets Visit pour une adresse IP et à compter le nombre d'objets uniques created dans ceux-ci.

def num_of_dates(ip_addr)  
    dates = [v.created for v in Visit.objects.filter(ip=ip_addr).order_by('-created')[0:100]] 
    unique_dates = set(dates) 
    return len(unique_dates) 
+0

Merci cela semble presque correct. Cependant, il renvoie toujours 100 plutôt que le nombre de jours. Je suppose que c'est parce que créé est un champ DateTime donc chaque date est unique. – FunLovinCoder

+0

Vous pouvez créer des objets Date à partir de l'objet DateTime pour obtenir des dates uniques au lieu d'horodatages uniques. Ou vous pouvez suivre la solution de @ fahhem qui semble plus propre. – rubayeet

1

Vous voulez probablement changer la valeur par défaut = pour created_on à auto_now_add depuis la datetime.utcnow ne met pas à jour si vous utilisez des serveurs autres que le serveur dev:

class Visit(models.Model): 
    created   = models.DateTimeField(auto_now_add=True,editable=False) 
    ip    = models.IPAddressField(editable=False) 

from datetime import datetime 
def days_for_100(ip_addr): 
    now = datetime.now() 
    dates = Visit.objects.filter(ip=ip_addr) 
    if dates.count()<100: 
    latest = dates.latest('-created') 
    else: 
    latest = dates.dates('created','day',order='DESC')[99] 
    return (now-latest).days # timedelta.days 

Cela renvoie combien de jours plus tôt il y a eu la 100e visite (ou depuis combien de temps la première visite a eu lieu s'il y a moins de 100 visites)

+0

J'ai essayé ceci (après avoir changé created_on en created) mais j'ai obtenu un index de liste hors erreur. En ce qui concerne l'auto_add_now, j'utilise une méthode personnalisée save() donc j'espère que c'est correct. – FunLovinCoder

+0

une sauvegarde personnalisée() devrait fonctionner, mais l'utilisation du code de Django pour auto_now_add réduit la quantité de code que vous devez maintenir/tester. Si vous obtenez une erreur hors plage, c'est parce que cette adresse IP n'a pas été visitée 100 fois, je la modifierai pour m'assurer que l'erreur ne se produira pas. – fahhem

+0

merci d'avoir essayé de le réparer. L'IP a eu plus de 600 visites, donc je ne sais pas pourquoi j'ai eu l'erreur. J'ai essayé le nouveau code, mais il donne toujours une erreur. Cette fois-ci: Invalid order_by arguments: ['--created']. – FunLovinCoder

Questions connexes