0

Ich habe eine E-Mail-/SMS-Benachrichtigungs-Engine erstellt. Eine Person oder Gruppe kann ein Objekt abonnieren und wenn das Objekt aktualisiert wird, werden die Personen/Gruppen per E-Mail/SMS über die Änderung informiert.Django: Erstellen einer Benachrichtigungs-Engine

Derzeit habe ich es, wie unten ausgeführt:

models.py

class Subscription(models.Model): 
    # subscribers 
    people = models.ManyToManyField(Person) 
    groups = models.ManyToManyField(Group) 

    # mandatory fields for generic relation 
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) 
    object_id = models.PositiveIntegerField() 
    content_object = GenericForeignKey() 

mixins.py

class NotificationMixin(object): 

    def perform_update(self, serializer): 
     model_name = str.lower(serializer.Meta.model) 
     old_obj = model.objects.get(id=serializer.data['id']) 
     obj = serializer.save() 
     self.notify(model_name, old_obj, obj) 

    def notify(self, model_name, old_obj, obj): 
     # All models have a GenericRelation field for reverse searching 
     subscriptions = Subscription.objects.filter(**{ model_name: obj }) 

     // *rest of logic to iterate over subscriptions and email people/groups 

generische Beziehungen Mit der django Content, kann ich eine Person abonnieren/Gruppe zu einem beliebigen Objekt.

Ich möchte die Möglichkeit hinzufügen, globale Subskriptionen mit demselben Abonnementmodell zu erstellen, sodass sie alle in derselben Tabelle gespeichert werden. Ein globales Abonnement verfügt nicht über ein Objekt, das verfolgt wird. Wenn jedoch ein Objekt eines bestimmten Modells ausgelöst wird, werden E-Mails gesendet.

Ich habe Probleme mit der Generalisierung meines Subskriptionsmodells, um eine Modellinstanz oder das Modell zum Auslösen einer Antwort akzeptieren zu können.

Die Funktionalität Ich möchte:

  1. Globale Abonnements

    • Leute/aktualisiert Gruppen durch, wenn jedes Objekt des Modells X
  2. Objektebene Abonnements

    geändert wird
    • Leute/aktualisiert Gruppen, wenn bestimmte Objekt
    • aktualisiert

Ist die aktuelle Modell/Architektur, dass er eine gute Möglichkeit, um dieses Problem zu gehen, oder soll ich das anders angehen?

Hinweis Das Frontend befindet sich in AngularJs, so dass es ausschließlich mit unserer Django API interagiert.

Antwort

0

Für alle, die eine Lösung für diese finden möchten, landete ich tun up:

class Subscription(models.Model): 
    """ 
    Model for subscribing to object changes. 

    Can be subscribed to any object or any model type. 
    Subcriptions: 
    model - if any object changes of this type that belongs to the company, update 
    object - if that specific object changes, update 

    To create: 
    Either give a content_object or a content_type. Content object is a model instance. Content type is a ContentType (i.e. Study, Product, etc.) 

    If it is created wrong, will just be lost in database forever (unless you know it's there, then delete it.) 
    """ 
    people = models.ManyToManyField(Person) 
    groups = models.ManyToManyField(Group) 
    trigger = models.CharField(max_length=50) 

    APP_LABELS = [apps to limit the available choices] 

    # for object subscription 
    # mandatory fields for generic relation 
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) 
    object_id = models.PositiveIntegerField(null=True) 
    content_object = GenericForeignKey('content_type', 'object_id') 

    def save(self, *args, **kwargs): 
     ''' 
     Save logic to validate the Subscription model. This is run after the native create() method. 
     ''' 
     # check if no content_object, then content_type must be defined by user 
     # probably not necessary since it will fail at creation if content_type isn't an instance of a ContentType, but good to double check 
     if not self.content_object: 
      if self.content_type.__class__ != ContentType: 
       if type(self.content_type) == str: 
        # if content_type is a string designating a model 
        self.content_type = ContentType.objects.get(model=self.content_type) 
       else: 
        # if content_type is a model class 
        self.content_type = ContentType.objects.get_for_model(Study) 

     apps = ', '.join(map(str, self.APP_LABELS)) 

     # check if content_type in our defined apps 
     if self.content_type.app_label not in apps: 
      raise ValidationError('Please select a content_object or content_type in apps: {0}'.format(apps)) 

     super(Subscription, self).save(*args, **kwargs) 
Verwandte Themen