2016-05-08 11 views
2

Ich lerne zu programmieren und habe ein Live-Django-Projekt, um mich motiviert zu halten. In meiner Django-App hinterlassen Benutzer Kommentare, während andere auf die genannten Kommentare antworten.Django Signale für die Verarbeitung eines einfachen Benutzerbenachrichtigungssystem

Jedes Mal, wenn ein Benutzer seine Homepage aktualisiert, errechne ich, ob er neue Antworten auf seine zuvor hinterlassenen Kommentare erhalten hat, und zeigt eine Benachrichtigung an, falls dies der Fall ist.

Dies skaliert nicht, denn wenn ein Benutzer eine Tonne Kommentare hinterlassen hat und daher eine Menge Antworten erhalten hat, dauert die Berechnung länger als für lurkers, die keinen Inhalt erstellen. Ich möchte die Erfahrung für diese Content-Ersteller verbessern.

Lesen deeper into it, ich habe festgestellt, Django Signale sind der Weg zu gehen. Zum Beispiel kann jedes Mal, wenn eine neue Antwort hinterlassen wird, ein Signal post_save() ausgelöst werden, das empfangen werden kann und die Benachrichtigung für den Benutzer aktualisieren kann. Auf diese Weise werden die Benachrichtigungen aktualisiert, sobald die Antworten verfügbar sind - so wie es sein sollte.

Ich muss meinen Code umgestalten, und ich bin immer noch verschwommen auf die Implementierungsdetails der oben genannten. Kann mir jemand ein kurzes anschauliches Beispiel dafür geben, wie ich das oben genannte erreichen kann? Es wird mich beginnen.


Derzeit Benutzerantwortverarbeitung in der form_valid Methode eines CBV in meinem views.py class PublicreplyView(CreateView) behandelt. Ich schätze, ich kann das folgende als eine Methode in meinem CBV einschließen?

from django.db.models.signals import post_save post_save.connect(form_valid, sender=User)

Und dann an anderer Stelle habe ich eine andere CBV, die die Benachrichtigungen für jeden Benutzer verarbeitet, sobald sie die Homepage aktualisieren. Ich denke, ich muss das komplett neu schreiben. Wie ich schon sagte, ich bin an dieser Front verschwommen.

Würde mich freuen, jemanden zu führen, was ich mit einem illustrativen, einfachen Beispiel tun soll. Vielen Dank!


p.s. Ich bin auf Django < 1.8.

+1

Es ist eine gute Frage, aber es ist ziemlich breit, vielleicht zu breit für SO. Wenn Sie Ihre Beschreibung des Problems lesen, klingt es so, als würden Sie etwas übersehen: Wenn Sie die Benachrichtigungen nicht jedes Mal neu berechnen möchten, wenn die Seite angezeigt wird, müssen Sie sie speichern. Das bedeutet, dass Sie in Ihrem post_save die Benachrichtigungen für den Benutzer irgendwo in DB speichern/aktualisieren. Und wenn (s) er die Startseite sieht, den gleichen Wert in der DB aktualisieren (verringern). – Djizeus

+0

@Djizeus: Wie wäre es, wenn ich 'post_save' für die Methode' form_valid' eines CBV verwende? Ist das korrekt? –

Antwort

3

@Djizeus gab einen guten Überblick in seinem Kommentar, und ich gebe Ihnen ein vollständiges Beispiel. Ich würde ein separates Modell für Benachrichtigungen erstellen und sie mit post_save-Signal bei der Erstellung von Kommentaren erstellen. Ich würde diesen Code jedoch nicht als gültig einstufen, sondern das post_save-Signal im Kommentarmodell verwenden. Auf diese Weise haben Sie eine sauberere Codetrennung. Wenn Sie sich entscheiden, z. Wenn Sie sich entscheiden, PublicReplyView neu zu gestalten, müssen Sie wahrscheinlich keinen Signalcode berühren.

Django feuert bereits post_save Signale, wenn Sie Kommentare speichern, also müssen Sie nur auf sie hören und sie verarbeiten. Um dies zu tun, erstellen signals.py Datei:

from django.dispatch import receiver 
from django.db.models.signals import post_save 
from .models import Comment, Notification 

@receiver(post_save, sender=Comment) 
def auto_create_notification(sender, instance, created, **kwargs): 
    if created: 
     # instance holds the new comment (reply), but you also have to fetch 
     # original comment and the user who created it 
     parent_comment = instance.parent_comment 
     parent_user = parent_comment.user    
     Notification.objects.create(user=parent_user, 
            comment=parent_comment, 
            type="reply_created") 

dieses Signal an Haken, müssen Sie erstellen/bearbeiten zwei weitere Dateien. Fügen Sie diese auf Ihre apps.py:

from django.apps import AppConfig 

# change Comment with your app name 
class CommentConfig(AppConfig): 

    name = 'comment' 
    verbose_name = 'Comment' 

    def ready(self): 
     import comment.signals 

Fügen Sie diese auf Ihre __init__.py:

default_app_config = 'comment.apps.CommentConfig' 

In Bezug auf Ihre Homepage-Ansicht Umsetzung hängt es was zeigen Sie auf Ihrer Homepage. Wenn Sie nur Benachrichtigungen anzeigen, ist Notification ListView eine gute Wahl.Wenn Sie eine Mischung aus verschiedenen Inhalten haben, würde ich wahrscheinlich TemplateView verwenden und alle Inhalte abrufen, die Sie in der Methode get_context_data() anzeigen müssen.

Verwandte Themen