0

我一直在建立一個電子郵件/短信通知引擎。一個人或一組可以訂閱一個對象,如果該對象得到更新,那麼將通過電子郵件/短信向人/組通知變化。Django:製作通知引擎

目前,我已經如下實現它:

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 

使用Django的ContentType的一般關係,我可以訂閱一個人/組到任何對象。

我想添加使用同一個Subscription模型創建全局訂閱的功能,以便它們全部存儲在同一個表中。全球訂閱不會有它正在跟蹤的對象,但是當某個特定模型的任何對象被觸發時,電子郵件將被髮送。

我無法一般化我的訂閱模型,以便能夠接受模型實例或觸發響應的模型。

的功能我想:

  1. 全局訂閱

    • 人/組由如果模型X的任何對象改變
  2. 對象級別訂閱

    更新
      如果特定對象進行更新

是當前的模型/架構,我有一個很好的方式去了解這個問題

  • 人/組更新,或者我應該接近這個不同?

    注意前端位於AngularJs中,所以這隻與我們的django api交互。

  • 回答

    0

    對於任何人誰可能希望找到一個解決這個問題,我落得這樣做:

    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)