django - 信号不起作用

Kak*_*kar 34 django django-signals

我正在尝试从其状态创建用户的活动流.

楷模:

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)
Run Code Online (Sandbox Code Playgroud)

但是,虽然我创建了一个新状态,但它不会根据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)
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?请帮我解决这个问题.我将非常感激.谢谢.

更新:

但是,这样做会创建活动:

@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
        )
Run Code Online (Sandbox Code Playgroud)

为什么以上不适用呢?

cat*_*ran 83

好像你post_save.connect没有被执行.你应该在signals某处导入.对于django 1.7,建议在app的config ready()函数中执行此操作.阅读"这段代码应该在哪里生活?" 文档中的旁注.

例如,如果您的应用被调用activity:

活动/ __ init__.py

default_app_config = 'activity.apps.ActivityAppConfig'
Run Code Online (Sandbox Code Playgroud)

活动/ apps.py

from django.apps import AppConfig

class ActivityAppConfig(AppConfig):
    name = 'activity'

    def ready(self):
        import activity.signals
Run Code Online (Sandbox Code Playgroud)

并且不要忘记将dispatch_uid添加到您的connect()通话中:

post_save.connect(create_activity_item, sender=Status,
                  dispatch_uid="create_activity_item")
Run Code Online (Sandbox Code Playgroud)

UPDATE:name属性ContentType始终为小写.所以你应该将if语句改为:

if ctype.name == 'status':
Run Code Online (Sandbox Code Playgroud)

  • 你好.我按照你的回答做了.但它仍然没有创造任何活动.在`__init __.py`中我添加了`default_app_config ='activities.apps.ActivityAppConfig'`作为活动是应用程序的名称.然后在应用程序中添加了一个新的apps.py文件,同时将`ActivityAppConfig`的名称字段更改为'activities'.然后添加`dispatch_uid`. (3认同)
  • django 文档有这个,但它们使它看起来如此可选,除非所有卫星都对齐,否则你不知道什么都不起作用 (2认同)

小智 22

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

  1. __init__.py,输入行

    default_app_config = 'AppName.apps.AppnameConfig'
    
    Run Code Online (Sandbox Code Playgroud)
  2. apps.py文件中,放置块

    from django.apps import AppConfig
    
    
    class AppnameConfig(AppConfig):
        name = 'AppName'
    
        def ready(self):
            import AppName.signals
    
    Run Code Online (Sandbox Code Playgroud)


小智 11

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

  • 任何人都知道为什么这有效? (3认同)

Jar*_*rad 6

简单、可扩展、可重复、可重用的答案是……

signals.py如果您打算在应用程序(例如:)中使用信号(例如posts:),只需养成每次都将此方法添加到您的类中的习惯即可apps.py AppConfig

def ready(self):
    from . import signals
Run Code Online (Sandbox Code Playgroud)

你不需要__init__.py像其他人说的那样触摸。然后你的信号就会起作用。