TransWikia.com

Каким образом можно уникализировать вывод из БД?

Stack Overflow на русском Asked by Aquinary on December 2, 2021

Имеется таблица сообщений следующего вида:
введите сюда описание изображения

Вопрос заключается в том, каким образом на основе этой таблицы вывести список диалогов.
Список диалогов имеет следующие требования:

  1. Пользователь не может видеть самого себя в этом списк
  2. Юзернейм собеседника не должен дублирваться.

Первый пункт криво-косо я реализовал, а вот на втором очень сильно застрял.

# model
# Получаем список всех диалогов пользователя (фильтруем по двум полям сразу)
dialogs = DialogModel.objects.filter(Q(u_from=u_id) | Q(u_to=u_id))
for dialog in dialogs:
    # Не допускает, чтобы пользователь видел самого себя в диалогах
    dialog.user = dialog.u_from
    if dialog.u_from_id == self.u_id:
         dialog.user = dialog.u_to

# template
# Просто вывод сообщений, на всякий случай
{% for dialog in dialogs %}
    {{ dialog.user }} {{ dialog.time }} <br>
{% endfor %}

На текущий момент результат выглядит так:
введите сюда описание изображения

Однако нужно, чтобы никнейм повторялся только единожды для отдельного собеседника.
Каким образом и на каком этапе можно это реализовать?

Заранее благодарю за помощь.

2 Answers

Решение было найдено:

# Получаем таблицу сообщений пользователя
dialogs = DialogModel.objects.filter(Q(u_from=u_id) | Q(u_to=u_id))

# Превращаем QuerySet в список словарей
dialogs = dialogs.values('u_from__id', 'u_from__username', 'u_to__id', 'u_to__username', 'time')

# Делаем так, чтобы не видеть самого себя в списках диалогах
# Так же это можно реализовать через сравнение в шаблоне (это будет даже короче по коду),
# но я решил оставить эту логику во вьюхе и не раскидывать логику по всему проекту
for dialog in dialogs:
    dialog['username'] = dialog.pop('u_from__username')
    dialog['id'] = dialog.pop('u_from__id')
    if dialog['id'] == self.u_id:
        dialog['username'] = dialog.pop('u_to__username')
        dialog['id'] = dialog.pop('u_to__id')

# На выходе получаем список словарей с содержимым, вроде
# {'time': datetime.datetime(2020, 7, 23, 16, 47, 37, 600365), 'username': 'Гость13', 'id': 13}

# Так как в списке могут попадаться словари с одинаковым username, то удаляем дубликаты
dialogs = list({item['username']: item for item in dialogs}.values())

# В результате получаем список словарей без повторяющихся username, готовых к выводу

Answered by Aquinary on December 2, 2021

Можно проверить, если следующее сообщение от того же самого адресата, то не указывать dialog.user.

Ваш пример в который я добавил непроверенный псевдо-код:

# model
# Получаем список всех диалогов пользователя (фильтруем по двум полям сразу)
dialogs = DialogModel.objects.filter(Q(u_from=u_id) | Q(u_to=u_id))
i = 0
for dialog in dialogs:
    # Не допускает, чтобы пользователь видел самого себя в диалогах
    dialog.user = dialog.u_from
    if dialog.u_from_id == self.u_id:
        dialog.user = dialog.u_to
    nextItemIndex = i + 1
    if dialogs.length >= nextItemIndex and dialogs[nextItemIndex].u_from_id != self.u_id:
        dialog.user = ''
    i = nextItemIndex

# template
# Просто вывод сообщений, на всякий случай
{% for dialog in dialogs %}
    {{ dialog.user }} {{ dialog.time }} <br>
{% endfor %}

Answered by hwak on December 2, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP