我正在覆盖Django的delete_selected
管理员行动。我有一个模型(Person
)通过OneToOneField与另一个模型(Party
)相关联,而delete_selected
只删除原始模型,而不删除相关模型中的数据,让我“鬼行“在我的数据库中。看起来这样本身可能表明我的代码存在问题,因为我的假设是delete()
函数会级联删除相关模型。
无论如何,问题是,我的自定义delete()
函数首先删除Party
,然后Person
的OneToOneField为空并抛出错误。想法?
这是我的模特:
class Party(models.Model):
name = models.CharField(max_length=100)
...
class Person(models.Model):
party = models.OneToOneField(Party, editable=False)
firstName=models.CharField(max_length=60)
lastName=models.CharField(max_length=60)
def delete(self):
self.party.delete()
self.delete()
我的管理员:
class PersonAdmin(admin.ModelAdmin):
actions=['really_delete_selected']
def get_actions(self, request):
actions = super(PersonAdmin, self).get_actions(request)
del actions['delete_selected']
return actions
def really_delete_selected(self, request, queryset):
for obj in queryset:
obj.delete()
if queryset.count() == 1:
message_bit = "1 person was"
else:
message_bit = "%s people were" % queryset.count()
self.message_user(request, "%s successfully deleted." % message_bit)
really_delete_selected.short_description = "Delete selected entries"
...
错误:
AssertionError at /admin/common/person/
Party object can't be deleted because its id attribute is set to None.
答案 0 :(得分:1)
我不确定为什么会这样,但它确实......
我将模型的delete()
功能更改为:
def delete(self):
d = self.party.id
Party.objects.get(id__exact=d).delete()
我想这实际上是在做@Furbeenator所建议的,因为通过删除Party中的正确行,cascad也删除了Person中的正确行。在黑暗中随机拍摄的三种欢呼有时会起作用,嗯?
答案 1 :(得分:0)
Python使用缩进进行语义分析。您的def delete(self):
未正确缩进,因此它不会覆盖本机delete()方法。它应该在Person的缩进级别之下。像这样:
class Party(models.Model):
name = models.CharField(max_length=100)
...
class Person(models.Model):
party = models.OneToOneField(Party, editable=False)
firstName=models.CharField(max_length=60)
lastName=models.CharField(max_length=60)
def delete(self):
self.party.delete()
self.delete()
您的管理部分也是如此,它应该缩进为:
class PersonAdmin(admin.ModelAdmin):
actions=['really_delete_selected']
def get_actions(self, request):
actions = super(PersonAdmin, self).get_actions(request)
del actions['delete_selected']
return actions
def really_delete_selected(self, request, queryset):
for obj in queryset:
obj.delete()
if queryset.count() == 1:
message_bit = "1 person was"
else:
message_bit = "%s people were" % queryset.count()
self.message_user(request, "%s successfully deleted." % message_bit)
really_delete_selected.short_description = "Delete selected entries"
...