Evgenii Legotckoi
Evgenii Legotckoi25. Oktober 2018 02:47

Django - Tutorial 039. Private Nachrichten und Chats auf der Site hinzufügen - Teil 2 (Dialog und Chatzähler mit ungelesenen Nachrichten)

Es gab freie Zeit, um persönliche Nachrichten auf der Website zu korrigieren. Diese Funktionalität wird nicht sehr oft verwendet, daher bemühe ich mich nicht sehr, sie zu verbessern, obwohl es an der Zeit ist, diese Funktionalität angemessen zum Laufen zu bringen.

Zuvor gab es einen sehr großen Fehler, der darin bestand, dass der Zähler von Dialogen mit ungelesenen Nachrichten nicht angezeigt wurde, was dazu führte, dass der Benutzer, an den die Nachricht gesendet wurde, einfach nicht darauf achtete, weil sie wusste nichts von diesen Meldungen.

Jetzt habe ich diesen Mangel endlich behoben. Und innerhalb des vorherigen Codes werde ich zeigen, welche Korrekturen hinzugefügt wurden.


Ich habe über zwei Optionen nachgedacht, um Zähler für ungelesene Nachrichten zu organisieren. Vielmehr eine Option und ihre fortgeschrittenere Version.

  • Überprüfen Sie bei jeder Anfrage alle Chats, wählen Sie die neuesten Nachrichten aus ihnen aus und prüfen Sie, ob der Autor ein autorisierter Benutzer ist, für den Sie diese Nachricht überprüfen möchten. Wenn er nicht der Autor ist, dann prüfen wir, ob diese Nachricht gelesen wurde, wenn nicht, dann gilt dieser Dialog für diesen Benutzer als ungelesen. Die Anzahl solcher Dialoge wird als Anzahl der ungelesenen Dialoge betrachtet.
  • Und die zweite Option, für die ich mich entschieden habe, geht von derselben Logik aus, nur dass der Dialog oder Chat einen Fremdschlüssel zu der zuletzt hinzugefügten Nachricht haben muss. Dieser Schlüssel wird mit jeder neuen Nachricht aktualisiert. Dadurch entfällt die Notwendigkeit, Chat-Nachrichten abzurufen und sie zu sortieren, um die neueste Nachricht zu erhalten. Was meiner Meinung nach bei vielen Dialogen zu einem großen Overhead für die Datenbank führen kann.

Implementierung

Modelle.py

Lassen Sie uns der letzten Nachricht einen Fremdschlüssel sowie einen benutzerdefinierten Chat-Manager ChatManager hinzufügen.

# -*- coding: utf-8 -*-

#... Код из предыдущей части


class ChatManager(models.Manager):
    use_for_related_fields = True

    # Метод принимает пользователя, для которого должна производиться выборка
    # Если пользователь не добавлен, то будет возвращены все диалоги,
    # в которых хотя бы одно сообщение не прочитано
    def unreaded(self, user=None):
        qs = self.get_queryset().exclude(last_message__isnull=True).filter(last_message__is_readed=False)
        return qs.exclude(last_message__author=user) if user else qs


class Chat(models.Model):
    #... Код из предыдущей части

    # внешний ключ на последнее сообщение,
    # важный момент в том, что название класса Message пишем обычной строкой,
    # поскольку на момент чтения класса Chat интерпретатор Python ничего не знает о классе Message
    # Также необходимо добавить related_name, имя через которое будет ассоциироваться выборка данного сообщения из базы данных
    last_message = models.ForeignKey('Message', related_name='last_message', null=True, blank=True, on_delete=models.SET_NULL)

    objects = ChatManager()

    @models.permalink
    def get_absolute_url(self):
        return 'users:messages', (), {'chat_id': self.pk }


class Message(models.Model):
    #... Код из предыдущей части

receivers.py

Dies ist das erste Mal, dass ich eine solche Python-Datei in einem Django-Projekt schreibe. Sein Wesen besteht darin, dass dort Signal-Handler aus dem Modell deklariert werden. Tatsache ist, dass in Django beim Speichern eines Modellobjekts einige Signale ausgegeben werden, die behandelt werden können. Auf diese Weise können Sie eine konsistente Logik in eine separate Datei einfügen und den Rest des Projektcodes etwas übersichtlicher gestalten. Der Nachteil ist, dass dieser Code möglicherweise nicht offensichtlich ist, da es in anderen Teilen des Projekts keine Verweise auf diesen Code gibt.

# -*- coding: utf-8 -*-

from django.db.models.signals import post_save
from django.dispatch import receiver

from users.models import Message


# обработчик сохранения объекта сообщения
@receiver(post_save, sender=Message)
def post_save_comment(sender, instance, created, **kwargs):
    # если объект был создан
    if created:
        # указываем чату, в котором находится данное сообщение, что это последнее сообщение
        instance.chat.last_message = instance
        # и обновляем данный внешний ключ чата
        instance.chat.save(update_fields=['last_message'])

Aber einfach so funktioniert dieser Code nicht, da diese Datei auch in den Interpreter geladen werden muss.

Sie können dies in der Datei apps.py tun, wenn die Anwendung initialisiert wird

apps.py

Dies geschieht in der ready-Methode.

# -*- coding: utf-8 -*-

from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _


class UsersConfig(AppConfig):
    name = 'users'
    verbose_name = _('Users')

    def ready(self):
        import users.receivers

Anwendung

Jetzt, da Sie alles haben, was Sie brauchen, um die Anzahl der Dialoge mit ungelesenen Nachrichten zu erhalten, können Sie diese Informationen zum Vorlagen-Rendering-Kontext hinzufügen.

context['unreaded_dialogs_counter'] = user.chat_set.unreaded(user=user).count()

Wie man alte Dialoge repariert

Es müssen nur noch die alten Dialoge repariert werden, die bereits Meldungen enthalten. Dies kann über das Admin-Panel erfolgen, wenn Sie die entsprechende Aktion hinzufügen.

admin.py

# -*- coding: utf-8 -*-

from django.contrib import admin

from users import models


class ChatAdmin(admin.ModelAdmin):
    autocomplete_fields = ['members']
    search_fields = ('members',)
    actions = ['fix_last_messages']

    def fix_last_messages(self, request, queryset):
        for chat in queryset.all():
            chat.last_message = chat.message_set.all().order_by('-pub_date').first()
            chat.save(update_fields=['last_message'])

    fix_last_messages.short_description = "Fix last messages"


class MessageAdmin(admin.ModelAdmin):
    autocomplete_fields = ['chat', 'author']
    list_display = ('chat', 'author', 'message', 'pub_date', 'is_readed')


admin.site.register(models.Chat, ChatAdmin)
admin.site.register(models.Message, MessageAdmin)
Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Stabiles Hosting des sozialen Netzwerks EVILEG. Wir empfehlen VDS-Hosting für Django-Projekte.

Magst du es? In sozialen Netzwerken teilen!

Anton
  • 4. August 2020 02:19
  • (bearbeitet)

Здравствуйте, подскажите как именно должна выглядеть уже готовая вьюха с context? Не догоняю как его вставить

Anton
  • 4. August 2020 02:25

Может быть посоветуете как добавить необязательное поле + прокинуть его во вьюху что бы можно было отправлять небольшие документы.?

Anton
  • 5. August 2020 04:20

Этот вопрос я решил)

Evgenii Legotckoi
  • 5. August 2020 05:14

Добавляйте поле файла в модель сообщения. И в форме сообщения указывайте, что поле с файлом.

Kommentare

Nur autorisierte Benutzer können Kommentare posten.
Bitte Anmelden oder Registrieren
Letzte Kommentare
ИМ
Игорь Максимов5. Oktober 2024 07:51
Django – Lektion 064. So schreiben Sie eine Python-Markdown-Erweiterung Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas55. Juli 2024 11:02
QML - Lektion 016. SQLite-Datenbank und das Arbeiten damit in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssr8. Februar 2024 18:43
Qt Linux - Lektion 001. Autorun Qt-Anwendung unter Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Qt WinAPI - Lektion 007. Arbeiten mit ICMP-Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25. Dezember 2023 10:30
Boost - statisches Verknüpfen im CMake-Projekt unter Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
Jetzt im Forum diskutieren
J
JacobFib17. Oktober 2024 03:27
добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
JW
Jhon Wick1. Oktober 2024 15:52
Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…
КГ
Кирилл Гусарев27. September 2024 09:09
Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
F
Fynjy22. Juli 2024 04:15
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

Folgen Sie uns in sozialen Netzwerken