データベースから削除された外部キー値を変更したいと思います。だから私はその文書を見て、on_delete = models.SET(foo)メソッドを使いました。 https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.SETDjangoはmodels.SET on_deleteに自己を渡します
は、これは私のモデル定義
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
に呼び出された私の方法であります私はどの製品が削除されたのか分からないのです。私もこの答えで指定された信号を使用してみましたdjango model on_delete pass self to models.SET()
私も信号を使ってみましたが、それも動作しませんでした。私はこれに対して適切な解決策を見つけることができないようです。 誰かがこれを達成する方法について考えているかどうか教えてください。
EDIT
これが今の問題はDjangoは(デフォルトon_deleteをカスケードに設定されているもの)だけでなく、私の注文ラインを削除しようとすることです私は信号
@receiver(pre_delete, sender=Product)
def getDuplicateProduct(sender, **kwargs):
product = kwargs['instance']
orderlines = product.orderline_set.all()
#further processing
に使っていたコードです。また、on_DeleteをSET_NULLに設定すると、外部キーがNULLに設定されます。
EDIT -2 ここでは、私は完全のための完全な実施を投稿
@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()
EDIT-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()
"受信者方法での注文ラインの参照はありません。"何故なの?シグナルで使用したコードを投稿できますか? – solarissmoke
2回目の編集では、問題を引き起こしているのは「deepcopy」だと思います。 'post_delete'ハンドラに移動できるかどうか確認してください。また、それはclobbered(私は私の答えを編集した)を避けるために、クエリセットをコピーする必要があります。 – solarissmoke
@solarissmoke私はpost_deleteハンドラに深いコピーを移動しようとしましたが、それはうまくいくようですが、感謝と遅れて返事申し訳ありません、町から10日間行きました。 – Anurag