Показать только последнее непрочитанное сообщение, связанное с тем же пользователем Django - PullRequest
0 голосов
/ 05 мая 2019

У меня есть раскрывающийся список уведомлений, в котором отображаются непрочитанные сообщения во всех темах, частью которых является зарегистрированный пользователь.

Пример, Сэм и Джейн.

Джейн в 3-х темах с 3 разными людьми. Сэм отправил ей 6 сообщений подряд. Прямо сейчас в раскрывающемся уведомлении отображаются все 6 непрочитанных сообщений от Сэма, что неэффективно.

Даже если на красном непрочитанном уведомлении будет отображаться 6, в раскрывающемся списке должно отображаться только последнее непрочитанное сообщение от Сэма.

У меня проблемы с этим, потому что я не знаю, что фильтровать, чтобы извлечь / отобразить только последнее сообщение. Модель Notification имеет только 3 поля.

class Notification(models.Model):
    notification_user = models.ForeignKey(User, on_delete=models.CASCADE)
    notification_chat = models.ForeignKey(ChatMessage, on_delete=models.CASCADE)
    notification_read = models.BooleanField(default=False)

Когда пользователь отправляет сообщение, оно сохраняется как объект Notification с получающим пользователем как notification_user.

Так что сейчас у меня есть эта функция

def notification(request):
    if request.user.is_authenticated:
        notification = Notification.objects.filter(notification_user=request.user, notification_read=False)
        notification_read = Notification.objects.filter(notification_user=request.user, notification_read=True)
        return {
            'notification':notification,
            'notification_read':notification_read
        }
    return Notification.objects.none()

Отображает все уведомления read/unread, связанные с вошедшим в систему пользователем, но, очевидно, отображает все 6 сообщений от Сэма.

models.py

class Thread(models.Model):
    first        = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='chat_thread_first')
    second       = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='chat_thread_second')
    updated      = models.DateTimeField(auto_now=True)
    timestamp    = models.DateTimeField(auto_now_add=True)

    objects      = ThreadManager()

class ChatMessage(models.Model):
    thread      = models.ForeignKey(Thread, null=True, blank=True, on_delete=models.SET_NULL)
    user        = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='sender', on_delete=models.CASCADE)
    message     = models.TextField()
    timestamp   = models.DateTimeField(auto_now_add=True)

consumer.py (где создается уведомление)

  @database_sync_to_async
    def get_thread(self, user, other_username):
        return Thread.objects.get_or_new(user, other_username)[0]

    @database_sync_to_async
    def create_chat_message(self, me, msg):
        thread_obj = self.thread_obj
        return ChatMessage.objects.create(thread=thread_obj, user=me, message=msg)

    @database_sync_to_async
    def create_notification(self, other_user, msg):
        last_chat = ChatMessage.objects.latest('id')
        created_notification = Notification.objects.create(notification_user=other_user, notification_chat=last_chat)
        return created_notification

пример navbar.html

{% for notifications in notification_read|slice:"0:6" %}
                  <li><a href="{% url 'thread' user %}">
                    <span id="notification-{{notification.id}}">
                      '{{ notifications.notification_chat.message }}'
                      -{{ notifications.notification_chat.user }}
                    </span>
                  </a></li>

1 Ответ

1 голос
/ 05 мая 2019
Notification.objects.filter(
    notification_user=request.user, notification_read=True
).order_by('-notification_chat__timestamp')[:1]

Не забудьте добавить правильный order_by, иначе «последняя запись» будет немного случайной.

...