我想修改一个外键值,当它从数据库中删除。所以我看了医生,用on_delete=模型。SET(foo)方法.https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.SET
这是我的模型定义
class OrderLine(models.Model):
product = models.ForeignKey(Product, on_delete=models.SET(getDuplicateProduct), null=True)
quantity = models.PositiveSmallIntegerField(default=1)
finalPricePerUnit = models.PositiveIntegerField()
order = models.ForeignKey(Order, on_delete=models.PROTECT)
dateCreated = models.DateTimeField(auto_now=False, auto_now_add=True)
这是我的方法,被称为删除
def getDuplicateProduct(orderline):
productToDelete = orderline.product
# some logic to generate duplicate copy and returning it
然而这里的问题是,我不能将参数传递给这个方法,这就是为什么我不能知道删除了哪个产品。我还试着在_deletepass self to models.SET()上使用这个应答django模型中指定的信号
我也试过使用信号,但也没用。我似乎找不到合适的解决办法。如果有人对如何实现这一点有想法,请告诉我。
编辑
这是我在信号中使用的代码
@receiver(pre_delete, sender=Product)
def getDuplicateProduct(sender, **kwargs):
product = kwargs['instance']
orderlines = product.orderline_set.all()
#further processing
现在的问题是django也试图删除我的订单行(因为默认的\u delete设置为cascade)。如果我将on_Delete设置为set_NULL,它会将外键设置为NULL。
这是我正在使用的代码
@receiver(pre_delete, sender=Product)
def getDuplicateProduct(sender, **kwargs):
product = kwargs['instance']
orderlines = product.orderline_set.all()
product.name = product.name + ' ' + product.get_type_display()
newProduct = deepcopy(product)
newProduct.name = product.name + ' ' + product.get_type_display()
newProduct.pk=None
newProduct.id=None
newProduct.save()
product.duplicateProductId = newProduct.id
product.old_orderlines = orderlines
product.save()
@receiver(post_delete, sender=Product)
def handlePostDelete(sender, **kwargs):
product = kwargs['instance']
newProduct = Product.objects.get(id=product.duplicateProductId)
for orderline in product.old_orderlines:
orderline.product = newProduct
orderline.save()
编辑-3发布完整的实施情况。
@receiver(pre_delete, sender=Product)
def handlePreDelete(sender, **kwargs):
product = kwargs['instance']
orderlines = product.orderline_set.all()
shouldCreate=False
for orderline in orderlines:
if orderline.order.status>1:
shouldCreate=True
product.shouldCreate = shouldCreate
if shouldCreate:
product.old_orderlines = orderlines
product.save()
else:
product.save()
return None
@receiver(post_delete, sender=Product)
def handlePostDelete(sender, **kwargs):
product = kwargs['instance']
shouldCreate = product.shouldCreate
if shouldCreate:
newProduct = deepcopy(product)
newProduct.name = product.name + ' ' + product.get_type_display()
newProduct.pk=None
newProduct.id=None
newProduct.save()
# Do whatever you want with product.old_orderlines
for orderline in product.old_orderlines:
orderline.product = newProduct
orderline.save()
支持@ SalARISSUP答案,我认为正确的解决方案,但给你更多的选择,我将张贴此。如果您拥有产品
实例,则可以拥有其订单行
。例如,如果将相关的\u名称添加到
订单行.product
中,如下所示:
class OrderLine(models.Model):
product = models.ForeignKey(Product, related_name='orderlines')
然后,您可以在信号中执行以下操作:
@receiver(pre_delete, sender=Product)
def getDuplicateProduct(sender, **kwargs):
product = kwargs['instance']
orderlines = product.orderlines.all()
另一种方法是获取
订单行。
信号是正确的方法。
您可以从信号接收器获取订单行
:
@receiver(pre_delete, sender=Product)
def getDuplicateProduct(sender, **kwargs):
product = kwargs['instance']
orderlines = product.orderline_set.all()
# orderlines contains all the OrderLines foreign keyed to the product.
orderlines
是一个查询集,您可以对其进行迭代或批量更新。
编辑
事实证明,上面建议的方法是行不通的,因为当pre_delete
信号发出时,Django已经确定了它需要用on_delete
处理哪些相关模型,并将覆盖这些更改。
这种方法会起作用,尽管有点笨重:
首先,在pre_中删除
receiver:from copy import copy
@receiver(pre_delete, sender=Product)
def handlePreDelete(sender, **kwargs):
product = kwargs['instance']
# Store the OrderLines as a property of the object
# Have to copy it otherwise it will be empty later
product.old_orderlines = copy(product.orderline_set.all())
然后,在一个post_delete
接收器中:
@receiver(post_delete, sender=Product)
def handlePostDelete(sender, **kwargs):
product = kwargs['instance']
# Do whatever you want with product.old_orderlines
for line in product.old_orderlines:
# ...
在这两个事件之间,Django将在订单行上执行SET_NULL
(或您配置的任何内容)。
问题内容: 我正在建立一个包括条目之间关系的通讯簿。我为个人,公司,场地和角色有单独的模型。在我的索引页面上,我想列出每个模型的所有实例,然后对其进行过滤。这样一个人可以轻松地搜索和查找条目。我已经能够使用通用视图列出单个模型,并使用get_extra_context显示另一个模型: 我还可以使用自定义视图列出单个模型: 这是这两个测试的urls.py: 所以我的问题是“如何修改此参数以将更多模型
问题内容: 我有一个猫鼬模型与用户模型有关联,例如 当我实例化一个新模型时,我会做: 模型的构造函数需要使用许多参数,这些参数在架构更改时编写和重构很繁琐。有没有办法做类似的事情: 还是创建帮助器方法以生成JSON对象甚至将userId附加到请求正文的最佳方法?还是我什至没有想到的方式? 问题答案: 或者如果您要将userId复制到req.body中:
问题内容: 是否有可能做类似这样的一个东西,还是其他什么东西? 如果我可以扩展它,那就更好了: 问题答案: 如果和是模型中的字段,则可以使用**运算符将关键字参数传递到字典中。 假设你的模型称为MyModel: 至于第二个问题,字典必须是最后一个参数。同样,并且应该是模型中的字段。
问题内容: 这在Django 1.9中用form_kwargs修复。 我有一个看起来像这样的Django表单: 我称这种形式的东西是这样的: 登录用户在哪里。这按预期工作。 我的问题是,我现在想将此单一表单转换为表单集。我不知道的是在创建表单集时如何将会员信息传递给各个表单。根据文档来制作一个表单集,我需要做这样的事情: 然后我需要这样创建它: 现在如何以这种方式将affiliate = requ
为了使saucelabs代理能够在旧版本的量角器中工作,我们通过在下面的index.js中设置主机和端口来覆盖sendRequest方法: 量角器\node_modules\selenium-webdriver\http\index.js 现在,量角器允许您通过capabilities对象(如下所示)设置代理,该对象应该传递给index.js sendRequest名为'opt_proxy'的新参
我知道接受参数和,所以我已经尝试了2次(失败)来包装函数和args...: a.创建一个C样式的函数,该函数将调用传递给它的对象: 这会在GCC 4.8.5中导致以下错误: /usr/include/c++/4.8.2/functional:在'struct std::_bind_simple(std::_placeholder<1>,int))(int*)>>()>'的实例化中:/usr/inc