@nurzhannogerbek

Как отсортировать записи модели данных на основе данных других связанных моделей?

Здравствуйте! Помогите пожалуйста разобраться.

Есть модель данных Project (Проект). У каждого проекта есть скажем так разделы. Если быть точнее то модели данных (Сharacterictic, Task) связанные с проектом. Пользователи могут оставлять комментарии к объектам/записям модель данных Сharacterictic, Task. Информация о комментариях хранится в модели Сomment.

Необходимо отсортировать (order_by) список проектов, чтобы первым стояли те проекты в разделах которых последним оставили комментарий.

Например был оставлен комментарий к Task-у, который принадлежит проекту A. Затем через некоторое время был оставлен комментарий к Сharacterictic-ке, который принадлежит к проекту Б. Получается при сортировки нужно поставить Проект Б первым, а проект А после него.

models.py:
class Project(models.Model):
    name = models.CharField(_('Name'), max_length=250)
    create_time = models.DateTimeField(auto_now_add=True)  # Дата создания записи
    revision_date = models.DateTimeField(_('Date of last update'), auto_now=True) # Дата последнего обновления записи

class Characteristic(models.Model):
    project = models.ForeignKey(Project, on_delete=models.CASCADE)
    description = models.TextField(_('Description'))
    comments = models.ManyToManyField("Comment")
    create_time = models.DateTimeField(auto_now_add=True)
    revision_date = models.DateTimeField(_('Date of last update'), auto_now=True)

class Task(models.Model):
    project = models.ForeignKey(Project, on_delete=models.CASCADE)
    description = models.TextField(_('Description'))
    comments = models.ManyToManyField("Comment")
    create_time = models.DateTimeField(auto_now_add=True)
    revision_date = models.DateTimeField(_('Date of last update'), auto_now=True)

class Comment(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    text = models.TextField()
    created = models.DateTimeField(auto_now_add=True)
  • Вопрос задан
  • 527 просмотров
Решения вопроса 1
Не уверен, как сделать это через ORM, надо экспериментировать. Если кто-то предложит, будет интересно посмотреть. Если никто не предложит, то я бы сделал так.

class Characteristic(models.Model):
    project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name='characteristics')
    ...

class Task(models.Model):
    project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name='tasks')
    ...

...

import operator

latest_comments_by_category = Project.objects.values_list('id').annotate(
    Max('characteristics__comments__created'),
    Max('tasks__comments__created'),
)

latest_comments = [
    (project_id, max(characteristic_time, task_time))
    for project_id, characteristic_time, task_time in latest_comments_by_category
]

projects = [
    Projects.objects.get(id=project_id)
    for project_id, _ in sorted(latest_comments, key=operator.itemgetter(1), reverse=True)
]


Конечно, это допустимо лишь, если проектов не слишком много.
P. S. Скорее всего это какой-то блок статистики. Его можно кэшировать для ускорения страницы.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы