Django 无法级联删除相关的通用外键对象
Django failing to cascade-delete related generic foreign key object
我的模型中定义了以下内容:
class TaskLink(models.Model):
task = model.ForeignKey(Task)
link_choices = (
models.Q(app_label="accounts", model="location"),
# Other models are also linked to here.
)
linked_content_type = \
models.ForeignKey(
ContentType,
limit_choices_to=link_choices
)
linked_object_id = models.PositiveIntegerField()
linked_object = \
generic.GenericForeignKey(
'linked_object_content_type',
'linked_object_id'
)
此模型将 Task
对象与 link_choices
元组中的任何模型链接起来。在这种情况下,accounts.Location
模型在此列表中。
当删除 Location
对象导致相关 TaskLink
对象的级联删除时,我的问题就来了。删除失败并显示以下错误消息:
django.core.exceptions.FieldError: Cannot resolve keyword 'object_id' into field. Choices are: id, linked_object, linked_object_content_type, linked_object_content_type_id, linked_object_id, task, task_id
该视图是 django.views.generic.DeleteView
的一个实例,仅设置了 pk_url_kwarg
参数和模型(并且在调度方法中添加了权限装饰器);在我将 TaskLink
模型添加到组合之前,它工作 linked_object_fine。
我错过了什么?
编辑:这似乎是 Django 中的一个错误;当通过通用外键级联删除对象时,Django 会忽略您传递给 GenericForeignKey
字段的构造函数的字段名称字符串,而是查找 content_type
和 object_id
字段,其中,我的情况,不存在。这有效地将模型可能必须的通用外键数量限制为 1,除非您不会 运行 进行级联删除。
我已通过 Django 邮件列表发送此问题,因为该行为可能是故意的。
重命名 TaskLink 的字段名称
linked_content_type >>> content_type
linked_object_id >>> object_id
或在删除"Location"对象时写入预信号以删除链接对象"TaskLink"
from django.db.models.signals import pre_delete
from django.dispatch import receiver
@receiver(pre_delete, sender=Location, dispatch_uid='location_delete_signal')
def deleted_gfk_TaskLink(sender, instance, using, **kwargs):
ctype = ContentType.objects.get_for_model(sender)
obj = TaskLink.objects.get(linked_content_type=ctype, linked_object_id=instance.id)
obj.delete()
自定义信号参考:
https://micropyramid.com/blog/using-djangos-built-in-signals-and-writing-custom-signals/
我的模型中定义了以下内容:
class TaskLink(models.Model):
task = model.ForeignKey(Task)
link_choices = (
models.Q(app_label="accounts", model="location"),
# Other models are also linked to here.
)
linked_content_type = \
models.ForeignKey(
ContentType,
limit_choices_to=link_choices
)
linked_object_id = models.PositiveIntegerField()
linked_object = \
generic.GenericForeignKey(
'linked_object_content_type',
'linked_object_id'
)
此模型将 Task
对象与 link_choices
元组中的任何模型链接起来。在这种情况下,accounts.Location
模型在此列表中。
当删除 Location
对象导致相关 TaskLink
对象的级联删除时,我的问题就来了。删除失败并显示以下错误消息:
django.core.exceptions.FieldError: Cannot resolve keyword 'object_id' into field. Choices are: id, linked_object, linked_object_content_type, linked_object_content_type_id, linked_object_id, task, task_id
该视图是 django.views.generic.DeleteView
的一个实例,仅设置了 pk_url_kwarg
参数和模型(并且在调度方法中添加了权限装饰器);在我将 TaskLink
模型添加到组合之前,它工作 linked_object_fine。
我错过了什么?
编辑:这似乎是 Django 中的一个错误;当通过通用外键级联删除对象时,Django 会忽略您传递给 GenericForeignKey
字段的构造函数的字段名称字符串,而是查找 content_type
和 object_id
字段,其中,我的情况,不存在。这有效地将模型可能必须的通用外键数量限制为 1,除非您不会 运行 进行级联删除。
我已通过 Django 邮件列表发送此问题,因为该行为可能是故意的。
重命名 TaskLink 的字段名称
linked_content_type >>> content_type
linked_object_id >>> object_id
或在删除"Location"对象时写入预信号以删除链接对象"TaskLink"
from django.db.models.signals import pre_delete
from django.dispatch import receiver
@receiver(pre_delete, sender=Location, dispatch_uid='location_delete_signal')
def deleted_gfk_TaskLink(sender, instance, using, **kwargs):
ctype = ContentType.objects.get_for_model(sender)
obj = TaskLink.objects.get(linked_content_type=ctype, linked_object_id=instance.id)
obj.delete()
自定义信号参考:
https://micropyramid.com/blog/using-djangos-built-in-signals-and-writing-custom-signals/