我有一个带有自引用外键的模型Location
。删除位置的父级后,我想将其parent_id
设置为其祖父母的ID,但不出所料,以下内容会引发错误name 'parent' is not defined
:
class Location(Model):
parent = models.ForeignKey('self', models.SET(parent))
如果我要从此表中删除Colorado
:
| id | name | parent_id |
|----|----------|-----------|
| 1 | USA | NULL |
| 2 | Canada | NULL |
| 3 | Colorado | 1 |
| 4 | Utah | 1 |
| 5 | Denver | 3 |
| 6 | Boulder | 3 |
我希望结果看起来像这样:
| id | name | parent_id |
|----|----------|-----------|
| 1 | USA | NULL |
| 2 | Canada | NULL |
| 4 | Utah | 1 |
| 5 | Denver | 1 |
| 6 | Boulder | 1 |
答案 0 :(得分:0)
是的,错误是预期的,models.SET
可以采取可调用但它不接受参数因此问题仍然存在,因为我们无法访问被删除的对象,您尝试实现的内容可以由{处理{3}}信号:
from django.dispatch.dispatcher import receiver
from django.db.models.signals import post_delete
@receiver(post_delete, sender=Location,
dispatch_uid='some.unique.string.id.for.location.delete')
def location_post_delete_handler(sender, instance, **kwargs):
parent = instance.parent
Location.objects.filter(parent_id=instance.id).update(parent=parent)
答案 1 :(得分:0)
Aamir Adnan 的回答对我不起作用,因为在 post_delete 信号时刻实例已经没有 id 属性(我猜)。所以我使用了 pre_delete
# when a category is deleted, switchs its childrens parent attr to its own parent (or None)
@receiver(pre_delete,
sender=Category,
dispatch_uid='delete_category')
def category_post_delete_handler(sender, instance, **kwargs):
new_parent = instance.parent if instance.parent else None
Category.objects.filter(parent_id=instance.id).update(parent=new_parent)
我还必须将 on_delete 设置为 DO_NOTHING,这样它就不会丢弃 pre_delete 刚刚所做的更改。
parent = models.ForeignKey('self',
on_delete=models.DO_NOTHING, # handled via Category's pre_delete signal
verbose_name=_('parent'),
related_name='child_categories',
blank=True,
null=True)