Django. Статистика на сайте цитат
Есть проект - сайт, в котором пользователи могут постить цитаты, указывать автора цитаты и добавлять к ним категории. Смысл в том, что это будет сайт для ограниченного числа людей, поэтому определенные юзеры уже будут указаны в базе данных, то есть фиксированное число пользователей, больше не будет. Эти то юзеры и будут авторами данных цитат, а также редакторами: один человек что-то сказал(автор цитаты), второй(редактор цитаты) это запостил на сайте и указал автора. Так вот, мне бы хотелось иметь связь между Автором(не редактором) и цитатой, к которой его отнесли. Идея такая, чтобы у определенного юзера имелась статистика, в которой есть информация о том, к какой Категории цитат чаще приписывают Автора. Например, из категорий цитат "любовь", "смех" и "грусть" меня бы чаще заносили в Категорию "смех", ведь я чаще шучу, соответственно, цитаты на сайте, скорее всего, имели бы похожую категорию.
from django.db import models
from author.models import Profile
class QuotesHonors(models.Model):
quotes = models.TextField()
editor = models.ForeignKey(Profile, on_delete=models.DO_NOTHING,
related_name='quotes_editor')
author = models.ForeignKey(Profile, on_delete=models.DO_NOTHING,
related_name='quotes_author')
category = models.ManyToManyField(
'Category', related_name='quotes_category')
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self) -> str:
return str(self.quotes[:30])
class Category(models.Model):
title = models.CharField(max_length=150, db_index=True)
def __str__(self) -> str:
return str(self.title)
class Like(models.Model):
user = models.ForeignKey(Profile, on_delete=models.CASCADE,
related_name='user_like')
quotes = models.ForeignKey(QuotesHonors, on_delete=models.CASCADE,
related_name='quotes_like')
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
class Comment(models.Model):
user = models.ForeignKey(Profile, on_delete=models.CASCADE,
related_name='user_comment')
quotes = models.ForeignKey(QuotesHonors, on_delete=models.CASCADE,
related_name='quotes_comment')
body = models.TextField(max_length=300)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
first_name = models.CharField(max_length=150)
last_name = models.CharField(max_length=150)
user = models.OneToOneField(User, on_delete=models.CASCADE)
email = models.EmailField(max_length=250, blank=True)
# avatar = models.ImageField(default='avatars/gosling.jpg', upload_to='avatars/')
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self) -> str:
return str(self.first_name) + ' ' + str(self.last_name)
Давно не писал запросы в DjangoORM, но, что-то близкое к вашему решению будет выглядеть так:
предположим, что user
это объект модели Profile
, тогда
запрос user.quotes_author.all()
вернет вам QuerySet
из всех цитат пользователя. Tак как нам нужно узнать какая категория пользуется популярностью, добавим в выборку только интересующее нас поле:
user.quotes_author.all().values('category')
Далее, подсчитаем количество цитат в каждой категории и отсортируем по убыванию:
from django.db.models import Count
user.quotes_author.all().values('category').annotate(total=Count('category')).order_by('total')
В результате вернется QuerySet
с категориями, отсортированными по убыванию, т.е. самая популярная будет на 0 позиции. Можно получить ее сразу, добавив .first()
метод к запросу.
Более подробно про values
почитать тут, про annotate
тут, а про Count
- тут.