简体   繁体   中英

Django : Best way to Query a M2M Field , and count occurences

class Edge(BaseInfo):
source = models.ForeignKey('Node', on_delete=models.CASCADE,related_name="is_source")
target = models.ForeignKey('Node', on_delete=models.CASCADE,related_name="is_target")

def __str__(self):
    return '%s' % (self.label)

class Meta:
    unique_together = ('source','target','label','notes')


class Node(BaseInfo):
item_type_list = [('profile','Profile'),
                ('page','Page'),
                ('group','Group'),
                ('post','Post'),
                ('phone','Phone'),
                ('website','Website'),
                ('email','Email'),
                ('varia','Varia')
]

item_type = models.CharField(max_length=200,choices=item_type_list,blank = True,null=True)
firstname = models.CharField(max_length=200,blank = True, null=True)
lastname = models.CharField(max_length=200,blank = True,null=True)
identified = models.BooleanField(blank=True,null=True,default=False)
username = models.CharField(max_length=200, blank=True, null=True)
uid = models.CharField(max_length=200,blank=True,null=True)
url = models.CharField(max_length=2000,blank=True,null=True)   
edges = models.ManyToManyField('self', through='Edge',blank = True)

I have a Model Node (in this case a soc media profile - item_type) that has relations with other nodes (in this case a post). A profile can be the author of a post. An other profile can like or comment that post.

Question: what is the most efficient way to get all the distinct profiles that liked or commented on anothes profile's post + the count of these likes /comments.

        print(Edge.objects.filter(Q(label="Liked")|Q(label="Commented"),q).values("source").annotate(c=Count('source')))

Gets me somewhere but i have the values then (id) and i want to pass the objects to my template rather then.get() all the profiles again...

Result:

Thanks in advance

I ended up with iterating over the queryset and adding the objects that i wanted in a dictionary, if the object was already in dictionary, i would count +1 and add the relation in a nested list. This doesnt feel right but works for now.

  posts = Edge.objects.filter(source = self,target__item_type='post',label='Author')
    if posts:
        q = Q()
        for post in posts:
            q = q | Q(target=post.target)
        contributors = Edge.objects.filter(Q(label="Liked")|Q(label="Commented"),q)

        if contributors:
            for i in contributors:
                if i.source.uid in results:
                    if i.label in results[i.source.uid]['relation']:
                        pass
                    else:         
                        results[i.source.uid]["relation"].append(i.label)
                    if 'post' in results[i.source.uid]:
                        results[i.source.uid]['post'].append(i.target)
                    else:
                        results[i.source.uid]['post']=[i.target]
                else:
                    results[i.source.uid] = {'profile' : i.source , 'relation':[i.label],'post':[i.target]}  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM