Django: лучший способ запроса поля M2M и подсчета вхождений - PullRequest
0 голосов
/ 03 мая 2020
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)

У меня есть модельный узел (в данном случае это c медиа-профиль - item_type), который связан с другими узлами (в данном случае постом). Профиль может быть автором поста. Другому профилю может понравиться или прокомментировать это сообщение.

Вопрос: какой самый эффективный способ получить все отдельные профили, которые понравились или прокомментировали сообщение профиля пользователя + количество таких лайков / комментариев.

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

Получает меня где-то, но у меня есть значения тогда (id), и я хочу передать объекты в мой шаблон, а не .get () все профили снова ...

Результат:

Заранее спасибо

1 Ответ

0 голосов
/ 07 мая 2020

Я закончил итерацией по набору запросов и добавил нужные объекты в словарь, если объект уже был в словаре, я бы посчитал +1 и добавил отношение во вложенный список. Это не правильно, но пока работает.

  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]}  
...