2015-01-26 89 views
1

我對用戶的活動模式:Django的 - 通過模型類的不同字段篩選

class Activity(models.Model): 
    actor = models.ForeignKey(User) 
    action = models.CharField(max_length=100) 
    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    content_object = generic.GenericForeignKey('content_type', 'object_id') 
    pub_date = models.DateTimeField(auto_now_add=True, auto_now=False) 

    class Meta: 
     verbose_name = 'Activity' 
     verbose_name_plural = 'Activities' 
     ordering = ['-pub_date'] 

    def __unicode__(self): 
     return ("%s %s") % (self.actor.username, self.action) 

觀點:

def home(request): 
    if request.user.is_authenticated(): 
     user = request.user 
     userP = Person.objects.get_or_create(user=user) 
     userP = userP[0] 
     following = userP.get_following() 
     users = [] 
     actors = list(following.values_list('user', flat=True)) + [user.id] 
     activities = Activity.objects.filter(actor__in=actors)    

更新

假設3個用戶喜歡相同的狀態和user3是最後一個喜歡這種狀態。現在,這將創建3個活動,說「User1喜歡狀態」,「User2喜歡狀態」,「User3喜歡狀態」。我想要的只是每個狀態是最近一次的活動。所以在這種情況下,它會是「User3喜歡的狀態」。

狀態模型:

class Status(models.Model): 
    body = models.TextField(max_length=200) 
    image = models.ImageField(blank=True, null=True, upload_to=get_upload_file_name) 
    privacy = models.CharField(max_length=1,choices=PRIVACY, default='F') 
    pub_date = models.DateTimeField(auto_now_add=True, auto_now=False) 
    user = models.ForeignKey(User) 
    hearts = generic.GenericRelation(Heart, null=True, blank=True) 

class Heart(models.Model): 
    user = models.ForeignKey(User) 
    pub_date = models.DateTimeField(auto_now_add=True, auto_now=False) 
    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    content_object = generic.GenericForeignKey('content_type', 'object_id') 

更新

這是signals.py創建每個對象的活動(心臟或狀態):如果你的數據庫

def create_activity_item(sender, instance, signal, *args, **kwargs): 
    if kwargs.get('created', True): 
     ctype = ContentType.objects.get_for_model(instance) 
     if ctype.name == 'Status': 
      action = ' shared ' 

      activity = Activity.objects.get_or_create(
       actor = instance.user, 
       action = action, 
       content_type = ctype, 
       object_id = instance.id, 
       pub_date = instance.pub_date 
      ) 

     if ctype.name == 'Heart': 
      action = ' gave heart to ' 

      activity = Activity.objects.get_or_create(
       actor = instance.user, 
       action = action, 
       content_type = ctype, 
       object_id = instance.id, 
       pub_date = instance.pub_date 
      ) 

for modelname in [Status, Heart]: 
    post_save.connect(create_activity_item, sender=modelname, 
        dispatch_uid="create_activity_item") 
+0

您正在使用什麼數據庫? – almalki 2015-02-04 12:09:16

回答

0
activities = Activity.objects.filter(actor__in=users).distinct('content_type', 'object_id', 'action') 

不支持DISTINCT ON查詢,你可以做查詢通過查找不同值的對象手動運行:

unique_activities = [] 
activities = Activity.objects.filter(actor__in=users) 
for activity in activities: 
    unseen = True 
    for unique_activity in unique_activities: 
     if (activity.action == unique_activity.action and activity.content_type == unique_activity.content_type and activity.object_id == unique_activity.object_id): 
      unseen = False 
      break 
    if unseen: 
     unique_activities.append(activity) 

print unique_activities 
+0

它現在沒有顯示我任何活動。 – Kakar 2015-01-26 19:47:53

+0

真的嗎?和'Activity.objects.filter(actor__in = users)'給你活動? – 2015-01-26 19:59:24

+0

我改變它來指定'content_type'和'object_id'作爲獨立的字段(而不是GenericForeignKey)。它現在工作嗎? – 2015-01-26 20:01:26

0

這聽起來像是一個greatest-per-group問題。你可以試試這個:

activities = Activity.objects.filter(
    id__in=Activity.objects.values('content_type') \ 
     .annotate(max_id=Max('id')) \ 
     .values_list('max_id', flat=True) \ 
) 
0

這將PostgreSQL只工作:

Activity.objects.order_by('action', 'content_type_id', 'object_id', '-pub_date').distinct('action', 'content_type_id', 'object_id').filter(actor__in=actors)