Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django:创建通知引擎_Python_Django_Notifications_Functional Programming_Django Rest Framework - Fatal编程技术网

Python Django:创建通知引擎

Python Django:创建通知引擎,python,django,notifications,functional-programming,django-rest-framework,Python,Django,Notifications,Functional Programming,Django Rest Framework,我一直在构建一个电子邮件/短信通知引擎。一个人或一个组可以订阅一个对象,如果该对象得到更新,将通过电子邮件/短信通知该人/组该更改 目前,我已按如下方式实施: models.py mixins.py 使用django的ContentType泛型关系,我可以订阅任何对象的个人/组 我想添加使用相同订阅模型创建全局订阅的功能,以便它们都存储在同一个表中。全局订阅不会有它正在跟踪的对象,但当触发特定模型的任何对象时,将发送电子邮件 我无法将订阅模型推广到能够接受模型实例或触发响应的模型 我想要的功能是

我一直在构建一个电子邮件/短信通知引擎。一个人或一个组可以订阅一个对象,如果该对象得到更新,将通过电子邮件/短信通知该人/组该更改

目前,我已按如下方式实施:

models.py mixins.py 使用django的ContentType泛型关系,我可以订阅任何对象的个人/组

我想添加使用相同订阅模型创建全局订阅的功能,以便它们都存储在同一个表中。全局订阅不会有它正在跟踪的对象,但当触发特定模型的任何对象时,将发送电子邮件

我无法将订阅模型推广到能够接受模型实例或触发响应的模型

我想要的功能是:

全局订阅

如果模型X的任何对象发生更改,则更新人员/组 对象级订阅

如果更新了特定对象,则更新人员/组 当前的模型/体系结构是我解决这个问题的好方法,还是我应该以不同的方式处理这个问题


请注意,前端是AngularJs,因此它专门与我们的django api交互。

对于任何想找到解决方案的人,我最后做了:

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)

你是如何使用触发器字段的?嗨@schlumpfpirat,不幸的是我不记得我是如何触发的。我已经好几年没有用Django编码了,对不起!我猜它是通过cronjob或系统正在侦听的订阅事件触发的。
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
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)