为什么 Django 模型信号不起作用?
Why Django model signals are not working?
我正在尝试根据用户状态创建 activity 用户流。
型号:
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
信号创建一个新的 activity。
信号:
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)
我做错了什么?请帮我解决这个问题。我将不胜感激。谢谢。
更新:
但是这样做会创建 activity:
@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
)
为什么上面的方法不起作用?
您的 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")
更新:ContentType
的 name
属性始终为小写。因此,您应该将 if
语句更改为:
if ctype.name == 'status':
无需触摸 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)
假设您的应用程序名称是 blog
,在项目的 settings.py 文件中确保在主项目的 INSTALLED_APP 变量中注册 blog
应用程序settings.py 文件为 blog.apps.BlogConfig
而不仅仅是 blog
。这对我有用。
如果您在 signals.py
中编写的所有内容都正确但无法正常工作,请检查这些步骤...(假设在名为 AppName 的应用中)
在__init__.py
中,把行
default_app_config = 'AppName.apps.AppnameConfig'
在apps.py
文件中,放入块
from django.apps import AppConfig
class AppnameConfig(AppConfig):
name = 'AppName'
def ready(self):
import AppName.signals
我正在尝试根据用户状态创建 activity 用户流。
型号:
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
信号创建一个新的 activity。
信号:
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)
我做错了什么?请帮我解决这个问题。我将不胜感激。谢谢。
更新:
但是这样做会创建 activity:
@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
)
为什么上面的方法不起作用?
您的 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")
更新:ContentType
的 name
属性始终为小写。因此,您应该将 if
语句更改为:
if ctype.name == 'status':
无需触摸 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)
假设您的应用程序名称是 blog
,在项目的 settings.py 文件中确保在主项目的 INSTALLED_APP 变量中注册 blog
应用程序settings.py 文件为 blog.apps.BlogConfig
而不仅仅是 blog
。这对我有用。
如果您在 signals.py
中编写的所有内容都正确但无法正常工作,请检查这些步骤...(假设在名为 AppName 的应用中)
在
__init__.py
中,把行default_app_config = 'AppName.apps.AppnameConfig'
在
apps.py
文件中,放入块from django.apps import AppConfig class AppnameConfig(AppConfig): name = 'AppName' def ready(self): import AppName.signals