标签: django-signals

Django - 我怎么_not_发送信号?

我为我的模型编写了一些智能通用计数器和管理器(以避免select count查询等).因此,我为post_save做了一些重要的逻辑.

我想在没有必要的时候阻止处理信号.我想完美的界面将是:

instance.save(dispatch_signal=False)
Run Code Online (Sandbox Code Playgroud)

我怎么能做到这一点?


更新

有关我正在做什么的更多信息,如果有人感兴趣:

  1. 通用计数器存储在单独的表中
  2. 每次Django对对象列表进行分页时,它都会调用我的自定义管理器的overriden count()方法,该方法基本上检索适当对象类的静态计数器值.
  3. 信号触发计数器更新的逻辑,这有点复杂,因为它检查相关模型的许多方面(即它必须基于嵌套的类别树生成可见性属性).我不能把这个逻辑放在Model.save()中,因为一个计数器依赖于许多不同的模型.我希望将这种逻辑整合在一起,而不是散布的碎片.
  4. 我正在对我的一些模型进行反规范化,所以我在表格中重写(复制)某些值.
  5. 出于测试目的,我运行我的小命令扩展 - Dilla,以填充随机数据.
  6. 我注意到不需要的信号触发,因此我希望它们有条件地运行.

希望它足够清楚.请原谅我的语言错误.

python django django-signals

4
推荐指数
3
解决办法
3917
查看次数

使用 Django 的 post_save() 信号

我有两个表:

class Advertisement(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    author_email = models.EmailField()

class Verification(models.Model):
    advertisement = models.ForeignKeyField(Advertisement)
    key = models.CharField(max_length=32)
Run Code Online (Sandbox Code Playgroud)

我需要在添加新广告后自动填充验证表。

def gen_key(sender, instance, created, **kwargs):
    if created:
        from hashlib import md5
        vkey = md5("%s%s" % (instance.author_email, instance.created_at))
        ver = Verification(advertisement=instance)
        ver.key = vkey
        ver.save()

post_save.connect(gen_key, sender=Advertisement)
Run Code Online (Sandbox Code Playgroud)

当然是行不通的。Django 1.2 问:我应该怎么做?


好了,解决了一半。
问题是父模型的 post_save() 不调用子模型。
所以你可以通过直接提供子类来解决它。

class Advertisement(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    author_email = models.EmailField()

class Sale(Advertisement):
    rooms = models.IntegerField(max_length=1)
    subway = models.ForeignKey(Subway)

class Verification(models.Model):
    advertisement = models.ForeignKeyField(Advertisement)
    key = models.CharField(max_length=32)

def gen_key(sender, instance, created, …
Run Code Online (Sandbox Code Playgroud)

python django-signals

4
推荐指数
1
解决办法
7357
查看次数

在测试用例(单元测试)中,无法捕获Django pre_save信号

在Django中,我捕获pre_save信号的代码效果很好.但是,在tests.py中的测试用例中,信号处理程序无法接收任何内容.这个问题有什么暗示吗?

  • 我的测试用例和信号处理程序似乎在不同的应用程序中.这是问题的原因吗?

python django unit-testing django-signals django-models

4
推荐指数
1
解决办法
1655
查看次数

动态上传路径 - 包括原始字段

我有一个带有多个ImageFields的Django模型,并使用callable来确定上传路径.我想在上传路径中包含原始上传字段的名称,在本例tiny中为small,mediumpress.

我能想到的唯一方法是创建一个替换file.nameuuid 的pre_save接收器.然后upload_to callable通过比较来找到匹配filename.这样做不是一种不那么黑客的方式吗?

class SomeDjangoModel(models.Model):

    IMAGE_SIZES = ('tiny', 'small', 'medium', 'press')

    def image_path(self, filename):
        """ Example return: [some-django-model]/[medium]/[product1].[jpg] """
        size = None
        for field_name in self.IMAGE_SIZES:
            field_fn = getattr(getattr(self, field_name), 'name', '')
            if field_fn == filename.rpartition('/')[2]:
                size = field_name
                break

        return u'{}/{}/{}.{}'.format(
            slugify(self._meta.verbose_name),
            size or 'undetermined',
            self.slug,
            filename.rpartition('.')[2].lower(),
        )

    tiny = models.ImageField(upload_to=image_path, blank=True, null=True)
    small = models.ImageField(upload_to=image_path, blank=True, null=True)
    medium = models.ImageField(upload_to=image_path, blank=True, null=True)
    press = models.ImageField(upload_to=image_path, …
Run Code Online (Sandbox Code Playgroud)

python django django-signals django-models

4
推荐指数
1
解决办法
359
查看次数

django如何在更新用户时发送post_save信号?

阅读了文档,

https://docs.djangoproject.com/en/dev/topics/signals/

我在我的signals.py文件中创建了这个:

from django.db.models.signals import post_save
from django.dispatch import receiver
from models import User

from models import Story

@receiver(post_save, sender=User)
def create_initial_story(sender,instance, signal, created, **kwargs):
    print "helloooo!"
    if created:
        Story(user = instance, title = 'Random Stories', description="Random stories", is_closed = False, is_random = True).save()
Run Code Online (Sandbox Code Playgroud)

从我读到的,我认为我需要做的就是发送信息.好吧,那并创建一个新用户(我使用django注册框架)然而,没有发送任何东西(好吧,我没有做任何接收器方法).我还删除了@receiver注释的"sender = User"参数 - 离开

@receiver(post_save)
Run Code Online (Sandbox Code Playgroud)

但那没有关系.没有任何内容输出到控制台,没有保存新数据... 当用户保存时,我是否需要从用户发送信号?如果是这样,我该怎么做?我正在使用django-registration,所以我有一个UserProfile定义...我的意思是,在哪里(在什么文件/方法中)我会告诉用户发送信号?

django django-signals

4
推荐指数
2
解决办法
1万
查看次数

django post_save从发送模型中调用?

我有一个非常简单的模型:

class Badge(models.Model):

    name = models.CharField(max_length=16, help_text="Name for Badge")
    category = models.ForeignKey(BadgeCategory, help_text="Category for badge")
    description = models.CharField(max_length=32, help_text="A brief description")
    file = models.ImageField(upload_to=format_badge_name)

    signals.post_save.connect(create_badge, sender=Badge)
Run Code Online (Sandbox Code Playgroud)

我知道在signals.py中我的create_badge函数有效.如果我发送它没有发送者的值,它说发件人是一个LogEntry对象.我想/需要在post_save脚本中引用一些实例信息,如下所示:

def create_badge(sender, instance, created, **kwargs):

    from userinfuser.ui_api import UserInfuser
    from django.conf import settings

    if created:
        api_key = settings.API_KEY
        api_email = settings.API_EMAIL

        ui = UserInfuser(api_email, api_key)
        ui.create_badge(instance.category.name, instance.name, instance.description, instance.file.url)
Run Code Online (Sandbox Code Playgroud)

我在哪里可以调用我的post_save调用,以便它知道徽章(我假设这是修复?

谢谢.

python django django-signals django-models

4
推荐指数
1
解决办法
1万
查看次数

Django 删除而不调用信号

我使用信号来处理对象被删除、保存、更新等时应该始终完成的事情。但是,有时我不想调用保存信号,所以我使用

Model.objects.filter(id=instance.id).update(field=value)

而不是实例的 save 方法:

instance.save()

在删除对象的情况下,有时我不想调用删除信号,但我还没有找到避免调用它们的方法。有办法吗??

更新:

我正在使用 django 1.6.2 并像这样调用删除方法:

Model.objects.filter(id=instance.id).delete()

查询集上仍然调用删除信号。

django django-signals django-models

4
推荐指数
1
解决办法
3229
查看次数

编辑 Many_to_many 字段时避免 Django 中的重复信号

我想自动更新有关模型更改的外部应用程序。问题在于数据在事件<->用户之间存在多对多关系。我尝试使用“m2m_changed”信号

@receiver(m2m_changed, sender=models.Event.organisers.through)
def event_changed(sender, instance, action, *args, **kwargs):
    if "post" in action:
      # hey api here is the new list of organisers of this
Run Code Online (Sandbox Code Playgroud)

问题在于,如果我进行一项更改,删除一个用户并添加另一个用户,那么该代码将被调用两次!这不好,我不能忽略一种类型的操作,以防仅调用该操作。我曾想过将实例推入堆栈并忽略重复项,但这看起来很混乱。有没有办法让我自己的信号只触发一次?

python django django-signals django-models

4
推荐指数
1
解决办法
1661
查看次数

在 django admin 中显示 m2m_changed 信号的验证错误

我正在尝试验证 MyModel 和 Item 的变量 foo 是否相同,然后再将其添加为 m2m。如果不是,我想在管理员中提出 ValidationError 。

模型.py

class Item(models.Model):
    foo = models.CharField(max_length=200)    

class MyModel(models.Model):
    foo = models.CharField(max_length=200)
    items = models.ManyToManyField(Item)
Run Code Online (Sandbox Code Playgroud)

信号.py

@receiver(m2m_changed, sender=MyModel.items.through)
def my_validator(sender, instance, action, pk_set, **kwargs):
    if action == 'pre_add':
        if Item.objects.filter(id__in=pk_set, foo=instance.foo).count() != len(pk_set):
            raise ValidationError({'items': ["Foo doesn't match"]})
Run Code Online (Sandbox Code Playgroud)

有没有办法让 ValidationError 在管理员中正确显示,而不是显示为 500 错误。

我无法想出一个解决方案来使用 MyModel 的 clean 方法来验证 foo 的相同值。任何建议表示赞赏。

python django django-signals django-admin django-validation

4
推荐指数
1
解决办法
1746
查看次数

Django信号如何对多个发送者和多个实例执行post_save方法?

我有两个Profile模型Company

模型.py

class Profile(models.Model):
    user = models.OneToOneField(User)
    company = models.ForeignKey('company.Company', null=True)
    phone = models.CharField(max_length=10, blank=True)

@receiver(post_save, sender=User)
@receiver(post_save, sender=Company)
def update_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)
        Profile.objects.create(company=instance)
    instance.profile.save()
Run Code Online (Sandbox Code Playgroud)

如您所见,Profile这是一个 user_model 扩展。当我只发送一个实例时,我已经做到了这一点。

模型.py

class Company(models.Model):
    user = models.OneToOneField(User)
    name = models.CharField(max_length=10, blank=True, unique=True)
    phone = models.CharField(max_length=10, blank=True)
Run Code Online (Sandbox Code Playgroud)

Company创建成功。我想 在创建公司时将该name字段保存到CompanyThe中。Profile

视图.py

def form_valid(self, form):
    company = form.save(commit=False)
    user = self.request.user
    name=form.cleaned_data['name']
    phone=form.cleaned_data['phone']
    company.name = name
    company.phone = phone
    company.user = …
Run Code Online (Sandbox Code Playgroud)

python django django-signals

4
推荐指数
1
解决办法
3890
查看次数