【问题标题】:Why Django model signals are not working?为什么 Django 模型信号不起作用?
【发布时间】:2015-03-23 23:24:16
【问题描述】:

我正在尝试根据用户的状态创建用户的活动流。

型号:

class Status(models.Model):
    body = models.TextField(max_length=200)
    image = models.ImageField(blank=True, null=True, upload_to=get_upload_file_name)
    privacy = models.CharField(max_length=1,choices=PRIVACY, default='F')
    pub_date = models.DateTimeField(auto_now_add=True, auto_now=False)
    user = models.ForeignKey(User)

class Activity(models.Model):
    actor = models.ForeignKey(User)
    action = models.CharField(max_length=100)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')
    pub_date = models.DateTimeField(auto_now_add=True, auto_now=False)

但是,虽然我创建了一个新状态,但它并没有从post_save 信号创建一个新活动。

信号:

from django.contrib.contenttypes.models import ContentType
from django.db.models.signals import post_save
from status.models import Status
from models import Activity

def create_activity_item(sender, instance, signal, *args, **kwargs):
    if kwargs.get('created', True):
        ctype = ContentType.objects.get_for_model(instance)

        if ctype.name == 'Status':
            action = ' shared '

            activity = Activity.objects.get_or_create(
                actor = instance.user,
                action = action,
                content_type = ctype,
                object_id = instance.id,
                pub_date = instance.pubdate
            )

post_save.connect(create_activity_item, sender=Status)

我做错了什么?请帮我解决这个问题。我将不胜感激。谢谢。

更新:

但是这样做会创建活动:

@receiver(post_save, sender=Status)
def create(sender, instance, **kwargs):
    if kwargs.get('created',True):
        ctype = ContentType.objects.get_for_model(instance)
        activity = Activity.objects.get_or_create(
            actor = instance.user,
            action = ' shared ',
            content_type = ctype,
            object_id = instance.id,
            pub_date = instance.pub_date
        )

为什么上面的方法不起作用呢?

【问题讨论】:

    标签: django django-models django-signals


    【解决方案1】:

    好像你的post_save.connect 没有被执行。您应该在某处导入signals。对于 django 1.7,建议在应用程序的 config ready() 函数中执行此操作。阅读文档中的 "Where should this code live?" 旁注。

    例如,如果您的应用名为activity

    activity/__init__.py

    default_app_config = 'activity.apps.ActivityAppConfig'
    

    activity/apps.py

    from django.apps import AppConfig
    
    class ActivityAppConfig(AppConfig):
        name = 'activity'
    
        def ready(self):
            import activity.signals
    

    别忘了将dispatch_uid 添加到您的connect() 通话中:

    post_save.connect(create_activity_item, sender=Status,
                      dispatch_uid="create_activity_item")
    

    更新ContentTypename 属性始终为小写。因此,您应该将if 语句更改为:

    if ctype.name == 'status':
    

    【讨论】:

    • 你好。我做了你在答案中所做的。但它仍然没有创建任何活动。在__init__.py 中,我添加了default_app_config = 'activities.apps.ActivityAppConfig',因为活动是应用程序的名称。然后在应用程序中添加一个新的apps.py文件,同时将ActivityAppConfig的名称字段更改为“活动”。然后添加dispatch_uid
    • 是的!现在它的工作。还有一件事。我是否总是必须通过创建 apps.py 来导入信号?为什么没有它就不行?
    • 好的,记住了!非常感谢!
    • django 文档有这个,但他们让它看起来很可选,除非所有的卫星都对齐,否则你几乎不知道什么都行
    • 我解决了我的问题,因为我没有在 INSTALLED_APPS 中正确注册配置。我定义了 'users.apps.UsersConfig' 而不仅仅是 'users' 然后为我工作。
    【解决方案2】:

    假设您的应用名称是blog,请确保在项目的settings.py 文件中将blog 应用在主项目的settings.py 文件的INSTALLED_APP 变量中注册为blog.apps.BlogConfig 而不仅仅是@ 987654324@。这对我有用。

    【讨论】:

    • 你救了我的命。
    • 有人知道为什么会这样吗?
    【解决方案3】:

    无需接触 apps.py 这对我有用。

    class MyModel(models.Model):
        """ MyModel fields go """
        body = models.TextField(max_length=200)
        pub_date = models.DateTimeField(auto_now_add=True, auto_now=False)
    
    
    def post_save_actions(sender, instance, created, **kwargs):
        if created:
            pass
            # post save actions if new instance is created,
            # do something with `instance` or another models
            # be careful about circular imports. \m/
    

    和信号挂钩,

    post_save.connect(post_save_user_actions, sender=MyModel)
    

    【讨论】:

    • 1 up for # 注意循环导入。 \m/
    【解决方案4】:

    如果您在signals.py 中正确写入所有内容但无法正常工作,请检查这些步骤...(假设在名为 AppName 的应用中)

    1. __init__.py 中,放行 default_app_config = 'AppName.apps.AppnameConfig'

    2. apps.py文件中,放块

      从 django.apps 导入 AppConfig

      类 AppnameConfig(AppConfig): name = 'AppName'

       def ready(self):
           import AppName.signals
      

    【讨论】:

      猜你喜欢
      • 2021-11-13
      • 1970-01-01
      • 2015-01-22
      • 2021-04-21
      • 2014-12-07
      • 2011-09-03
      • 1970-01-01
      • 2017-04-07
      • 1970-01-01
      相关资源
      最近更新 更多