我有一个关于django的问题.
我在这里有ManyToMany模型
class Product(models.Model):
name = models.CharField(max_length=255)
price = models.DecimalField(default=0.0, max_digits=9, decimal_places=2)
stock = models.IntegerField(default=0)
def __unicode__(self):
return self.name
class Cart(models.Model):
customer = models.ForeignKey(Customer)
products = models.ManyToManyField(Product, through='TransactionDetail')
t_date = models.DateField(default=datetime.now())
t_sum = models.FloatField(default=0.0)
def __unicode__(self):
return str(self.id)
class TransactionDetail(models.Model):
product = models.ForeignKey(Product)
cart = models.ForeignKey(Cart)
amount = models.IntegerField(default=0)
Run Code Online (Sandbox Code Playgroud)
对于创建的1个购物车对象,我可以插入尽可能多的新TransactionDetail对象(产品和金额).我的问题是.我该如何实现触发器?我想要的是每当创建交易细节时,我希望产品库存的数量减去transactiondetail中的金额.
我读过有关post_save()但我不确定如何实现它.也许这样的事情
when:post_save(TransactionDetail,Cart)#Cart对象,其中TransactionDetail.cart = Cart.id
post_save(TransactionDetail,
Cart) #Cart object where TransactionDetail.cart= Cart.id
Cart.stock -= TransactionDetail.amount
Run Code Online (Sandbox Code Playgroud) 我想知道是否有可能在对象创建时选择性地抑制Django信号(例如post_save或post_init),或者,发送它某些参数.
我所拥有的是一个User对象,可以在我的代码中以多种不同的方式创建.因此,要自动Profile为每个对象分配一个自定义对象User,我使用该post_save信号.但是,在一个特定情况下,我想要绑定到创建的Profile对象的额外信息.将它作为post_save信号的参数传递将是很好的,但它看起来不可能.
另一种选择是手动创建Profile对象,但是在User保存之后我需要这样做,否则Profile无法绑定到User实例.User但是,保存实例会导致Profile通过信号调用的函数创建另一个实例.
而且我不能只获得刚刚创建的Profile对象,因为这会导致'Profile' object is unsubscriptable错误.有什么建议?
更新:
以下是可能情况的示例:
def createUserProfile(sender, instance, created, **kwargs):
if created:
profile, created = Profile.objects.get_or_create(user=instance)
if extra_param:
profile.extra_param = extra_param
profile.save()
post_save.connect(createUserProfile, sender=User)
def signup(request):
...
extra_param = 'param'
user.save()
Run Code Online (Sandbox Code Playgroud)
如何extra_param将signup方法中的变量获取到createUserProfile方法,在该方法中将变量存储为Profile对象的一部分?
如果我将断开然后在单线程上下文中连接一些信号会影响其他线程使用的信号池吗?
更新
我会尝试更具体.
我正在为少数发件人使用post_save和pre_delete信号,这些发件人触发特定模型(一个特定模型)的全文引擎重建索引,这是全文引擎的主要内容源.
重新索引是通过Celery任务完成的,信号处理程序只需将重建索引任务分配给代理(在我的案例中是Redis).
一些post_save信号不应该触发重建索引(即 - 不应该调度Celery任务,pre_delete应该总是触发重建索引),因为一些模型更改与全文引擎内容无关(即状态更改,时间戳更改和其他一些).我无法在每个案例中验证处理程序kwargs中的update_fields,因为根据我的观察,管理站点保存操作没有指定那些.
我正在使用自定义上下文管理器,它将重新索引处理程序与特定发件人的post_save信号断开连接,将控制权返回到调用代码段,然后执行模型上的保存操作,并在控件传递回上下文管理器时,所有重建索引处理程序都在重新连接到特定发件人的post_save信号.
我想确保在单线程上下文中执行的上下文管理器中的断开/连接例程不会影响其他线程(即 - 在单线程上下文中断开的所有信号仍将在其他线程中连接).
谢谢!unkletee
我为我的模型编写了一些智能通用计数器和管理器(以避免select count查询等).因此,我为post_save做了一些重要的逻辑.
我想在没有必要的时候阻止处理信号.我想完美的界面将是:
instance.save(dispatch_signal=False)
Run Code Online (Sandbox Code Playgroud)
我怎么能做到这一点?
更新
有关我正在做什么的更多信息,如果有人感兴趣:
希望它足够清楚.请原谅我的语言错误.