2012-02-28 67 views
1

我正在重写Django的delete_selected管理员操作。我有一个通过OneToOneField与另一个模型(Party)关联的模型(Person),并且delete_selected仅删除原始模型,而不删除相关模型中的数据,从而在我的数据库中留下“虚影行”。看起来像这本身可能表明我的代码存在问题,因为我的假设是delete()函数会级联删除相关模型。通过OneToOneField自定义删除模型和关联模型

无论如何,麻烦的是,我的自定义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. 

回答

1

我不知道为什么这样的作品,但它确实...

我改变了我的模型delete()功能:

def delete(self): 
    d = self.party.id 
    Party.objects.get(id__exact=d).delete() 

我想这基本上是做什么@Furb eenator建议,通过删除Party中正确的行,该级联删除了Person中的正确行。在黑暗中随意拍摄三张欢呼声,有时会起作用,呃?

+0

非常好!这绝对是一个有趣的情况。 – Furbeenator 2012-03-01 22:48:13

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" 
     ... 
+0

对不起@Furbeenator,这是StackOverflow的结果不能很好地复制我的标签。现在已经修复了。原始代码仍然给我错误。 – reK1NDLE 2012-02-29 17:22:52

+0

对不起reK1NDLE。我会建议,是在Party对象而不是Person对象上创建Admin。这样,当您删除选定的Partys时,它将删除与其关联的Person对象。我认为你仍然可以通过PartyAdmin查看人物细节。这会起作用吗? – Furbeenator 2012-02-29 22:49:14

+0

派对没有在管理员中注册,因为根据用户的知识,所有的信息都存储在Person下的一个地方。这样写代码的原因是因为有一个名为Organization的模型与Party有一个“OneToOneField”。这使我不必重新输入Party for Organization中使用的代码。 – reK1NDLE 2012-03-01 15:27:40