我为我的模型编写了一些智能通用计数器和管理器(以避免select count查询等).因此,我为post_save做了一些重要的逻辑.
我想在没有必要的时候阻止处理信号.我想完美的界面将是:
instance.save(dispatch_signal=False)
Run Code Online (Sandbox Code Playgroud)
我怎么能做到这一点?
更新
有关我正在做什么的更多信息,如果有人感兴趣:
希望它足够清楚.请原谅我的语言错误.
我有两个表:
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) 在Django中,我捕获pre_save信号的代码效果很好.但是,在tests.py中的测试用例中,信号处理程序无法接收任何内容.这个问题有什么暗示吗?
我有一个带有多个ImageFields的Django模型,并使用callable来确定上传路径.我想在上传路径中包含原始上传字段的名称,在本例tiny中为small,medium或press.
我能想到的唯一方法是创建一个替换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) 阅读了文档,
我在我的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定义...我的意思是,在哪里(在什么文件/方法中)我会告诉用户发送信号?
我有一个非常简单的模型:
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调用,以便它知道徽章(我假设这是修复?
谢谢.
我使用信号来处理对象被删除、保存、更新等时应该始终完成的事情。但是,有时我不想调用保存信号,所以我使用
Model.objects.filter(id=instance.id).update(field=value)
而不是实例的 save 方法:
instance.save()
在删除对象的情况下,有时我不想调用删除信号,但我还没有找到避免调用它们的方法。有办法吗??
更新:
我正在使用 django 1.6.2 并像这样调用删除方法:
Model.objects.filter(id=instance.id).delete()
查询集上仍然调用删除信号。
我想自动更新有关模型更改的外部应用程序。问题在于数据在事件<->用户之间存在多对多关系。我尝试使用“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)
问题在于,如果我进行一项更改,删除一个用户并添加另一个用户,那么该代码将被调用两次!这不好,我不能忽略一种类型的操作,以防仅调用该操作。我曾想过将实例推入堆栈并忽略重复项,但这看起来很混乱。有没有办法让我自己的信号只触发一次?
我正在尝试验证 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 的相同值。任何建议表示赞赏。
我有两个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)