有没有人知道使用LINQ to SQL 做类似Django的signals方法?
我正在尝试记录何时插入新行以及更新某些列时,所以我真的只想要pre_save并post_save发出信号.
我可以通过使用定义为OnFooIDChanging()和OnFooIDChanged()(其中FooID是主键)的部分来对某些模型执行此操作,但这对于主键不是标识或由代码设置的模型不起作用.
对于那些,我可以使用OnValidate(),但这只会是pre_save,并且它使得处理数据库变得困难,因为OnValidate()调用来自DBContext.SubmitChanges(),当然不允许SubmitChanges()从内部调用第二个,使得post_save基本上不可能,就我而言可以看到.
我试图将"信息"对象连接到许多"客户"(参见下面的代码)
当一个Information对象更新时,我想向连接到Information的每个Customer发送电子邮件.
但是,当我记录信号收到的sold_to字段时,我总是得到保存之前的数据.
我猜这是因为它的ManyToManyField和数据存储在一个单独的表中,但是在更新所有关系之后不应该调用post_save信号吗?
有人建议解决方案吗?
class Customer
name = models.CharField(max_length=200)
category = models.ManyToManyField('Category',symmetrical=False)
contact = models.EmailField()
class Information
name = models.CharField(max_length=200)
email = models.EmailField(max_length=200)
mod_date = models.DateTimeField(auto_now=True)
sold_to = models.ManyToManyField(Customer, null=True, blank=True)
def send_admin_email(sender, instance, signal, *args, **kwargs):
from myapp import settings
for cust in instance.sold_to.all():
settings.debug(cust.name)
post_save.connect(send_admin_email, sender=Information)
Run Code Online (Sandbox Code Playgroud)
编辑:#django中的apollo13提醒我:"相关项目(被保存为多对多关系的东西)不会像你发现的那样保存为模型的保存方法的一部分." - http://groups.google.com/group/django-users/msg/2b734c153537f970
但自2006年7月9日起,我真的希望有一个解决方案.
我正在尝试开发一种拍卖类型系统,其中客户下订单,然后不同的商店可以为该订单提供价格.
该系统的一个有趣的部分是,当最初创建订单时,可用的商店将有60秒来提供他们各自的报价.当第一家商店提出要约时,"拍卖"现在只有接下来的20秒才能让其他商店自己出价.如果他们确实提出了另一个报价,在这个较小的分配时间内,那么这20秒就会刷新.只要有足够的时间,优惠可以继续收到,不能超过给定的最初60秒.
class Order(models.Model):
customer = models.ForeignKey(Customer)
create_time = models.DateTimeField(auto_now_add=True)
update_time = models.DateTimeField(auto_now_add=True)
total = models.FloatField(default=0)
status = models.IntegerField(default=0)
delivery_address = models.ForeignKey(DeliveryAddress)
store = models.ForeignKey(Store, null=True, blank=True, related_name='orders', on_delete=models.CASCADE)
credit_card = models.ForeignKey(CreditCard, null=True, blank=True, related_name='orders')
class OrderOffer(models.Model):
store = models.ForeignKey(Store, related_name="offers", on_delete=models.CASCADE)
order = models.ForeignKey(Order, related_name="offers", on_delete=models.CASCADE)
create_time = models.DateTimeField(auto_now_add=True)
Run Code Online (Sandbox Code Playgroud)
除了这些要求之外,我还想在新的优惠实时到达时更新客户.为此,我正在使用django-channelsWebSockets的实现.
我有以下consumers.py文件:
from channels.generic.websockets import WebsocketConsumer
from threading import Timer
from api.models import Order, OrderOffer
from django.db.models.signals import post_save
from django.dispatch import receiver
class OrderConsumer(WebsocketConsumer):
def …Run Code Online (Sandbox Code Playgroud) 我很难理解信号如何进入我的应用程序(以及它们如何工作期).以下是我认为适用的三个方面(根据我目前的知识):
我是完全偏离基地(我觉得我可能会).我收到信号和多线程混淆了吗?如果是这样,他们在应用程序中进行比较吗?它们只是用于解耦吗?另外,确保你提前实例化它们并且不使用本地函数(因为它们会收集垃圾)是什么?有人可以详细说明吗?我是否应该将它们全部放入请求中间件中以便我不必担心?
我正在尝试做这些提议的信号装饰器.除了有一个装饰器将装饰方法连接到一个信号(信号的发送者作为装饰器的参数),我想在类方法上使用装饰器.
我想像这样使用装饰器:
class ModelA(Model):
@connect.post_save(ModelB)
@classmethod
def observe_model_b_saved(cls, sender, instance, created, **kwargs):
# do some stuff
pass
Run Code Online (Sandbox Code Playgroud)
装饰者是:
from django.db.models import signals
def post_save(sender):
def decorator(view):
signals.post_save.connect(sender=sender, receiver=view)
return view
return decorator
Run Code Online (Sandbox Code Playgroud)
我这样做的错误是:
File "/Library/Python/2.6/site-packages//lib/python2.6/site-packages/django/dispatch/dispatcher.py", line 78, in connect AssertionError: Signal receivers must be callable.
我想问题是@classmethod返回一个不可调用的类方法对象.我真的不明白它是如何classmethod工作的,但我从这个参考页面推测,类方法对象在从类中访问之前不会被转换为可调用的,例如ModelA.observe_model_b_saved.有没有什么办法我可以(1)将我的方法定义为模型上的类或实例方法,以及(2)直接在方法定义上使用装饰器将其连接到信号?谢谢!
我在stackoverflow上找到了一个使用信号扩展django-registration和新字段的解决方案.这是链接:http://dmitko.ru/?p = 546.
我创建了扩展配置文件模型,扩展形式,为设置添加了必需的选项,定义了URL并显示了正确的表单,但只创建了普通用户(来自auth模块).为什么会这样?
account.models:
from django.db import models
from django.contrib.auth.models import User
from registration.signals import user_registered
import hashlib
class InheritedProfile(models.Model):
first_name = models.CharField("Name", max_length=50, blank=True, null=True)
last_name = models.CharField("Last name", max_length=50, blank=True, null=True)
pid = models.CharField("PESEL", max_length=11, blank=True, null=True)
street = models.CharField("Street", max_length=50, blank=True, null=True)
number = models.CharField("Flat/house number", max_length=10, blank=True, null=True)
code = models.CharField("Zip ", max_length=6, blank=True, null=True)
city = models.CharField("City", max_length=50, blank=True, null=True)
class Meta:
abstract=True
class UserProfile(InheritedProfile, User):
def upload_path(self, field_attname):
filename …Run Code Online (Sandbox Code Playgroud) 我对Django的信号不是很熟悉,可以使用一些帮助.
如何在保存实例之前修改pk_set?我是否必须向信号呼叫者返回一些东西(比如kwargs)?或者我保存instance自己?
作为一个简单的例子:我希望确保在pk=1保存时我的所有视频都包含类别.我该怎么做m2m_changed?
class Video(models.Model):
category = models.ManyToManyField('Category')
def video_category_changed(sender, **kwargs):
action = kwargs.pop('action', None)
pk_set = kwargs.pop('pk_set', None)
instance = kwargs.pop('instance', None)
if action == "pre_add":
if 1 not in pk_set:
pk_set.update( [ 1 ] ) # adding this to the set
# do something else?
# profit?
m2m_changed.connect( video_category_changed, sender=Video.category.through )
Run Code Online (Sandbox Code Playgroud) TL; DR:
我需要一种方法在信号发出后post_save自动触发自定义信号,有没有办法做到这一点?
我目前正在开发的Django库,需要自带了很多,并与云post_save在Django的信号,我想知道是否有可能触发另一信号之后的post_save,所以我可以实现我自己的,而不是介入post_save的情况下,一个项目,使用库需要做到这一点.
到目前为止,我知道信号预计将接收一个类作为发送者参数,如果我手动触发post_save中的信号,我将无所事事(我仍然会干预它).这有什么解决方法吗?我在文档中遗漏了什么吗?
例如,我正在使用post_save信号来触发配置文件数据的创建User。问题是,如果我User通过数据迁移创建对象,则post_save信号不会触发。
但是,如果我User通过 shell 或 创建实例UserCreationForm,一切似乎都正常工作。
我真的在文档中找不到任何可靠的东西。可以说我正在做这样的事情:
from django.db.models.signals import post_save
from django.dispatch import receiver
class Item(models.Model):
total_score = models.IntegerField()
def set_score(self):
...
class Review(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE)
score = models.IntegerField()
@receiver(post_save, sender=Review)
def my_handler(sender, **kwargs):
sender.item.set_score()
Run Code Online (Sandbox Code Playgroud)
我想做的是set_score()每当保存评论对象时调用项目对象。这是原子的吗?我绝对希望整个事情是原子的,因为保存评论但项目总分未更新的情况会导致错误。
django-signals ×10
django ×9
python ×4
aop ×1
asp.net-mvc ×1
decorator ×1
django-orm ×1
linq-to-sql ×1
m2m ×1