【问题标题】:Deleting SQL data in associated OneToOneField model from admin从管理员删除关联 OneToOneField 模型中的 SQL 数据
【发布时间】:2012-03-15 09:43:39
【问题描述】:

我有一个模型通过OneToOneField 引用另一个模型,因此当您使用 Django 的内置 delete_selected 管理操作时,关联模型的数据不会被删除。我想编写一个自定义管理操作来删除该关联模型中的数据。

这是我的模型:

class Party(models.Model):
    TYPE_CHOICES=(
        ('P','Person'),
        ('O','Organization')
    )
    partyType = models.CharField(max_length=1, choices=TYPE_CHOICES)
    name = models.CharField(max_length=100)
    comment = models.CharField(max_length=500,blank=True)
    accessIdCrossRef=models.IntegerField(blank=True, null=True)
    mailingLists = models.ManyToManyField(MailingList)
    inMainList=models.BooleanField(default=False)
    inSubList=models.BooleanField(default=False)

    class Meta:
        db_table='party'
        ordering=['name',]

    def __unicode__(self):
        return self.name

class Person(models.Model):
    party = models.OneToOneField(Party, editable=False)
    firstName=models.CharField(max_length=60)
    lastName=models.CharField(max_length=60)
    ...


    def save(self):
        if None == self.party :
            print 'Creating party for person'
            p = Party()
            p.partyType = 'P'
            p.save()
            self.party = p

        # Get address to set party name used in list
        city=""
        state=""
        postalCode=""
        try:
            partyAddress = PartyPostalAddress.objects.get(party=self.party)
            address = partyAddress.postalAddress
            city=address.city
            state=address.state
            postalCode=address.postalCode
        except PartyPostalAddress.DoesNotExist:
            pass

        self.party.name = '%s, %s - %s, %s %s' %(self.lastName, self.firstName, city, state, postalCode)
        self.party.save()
        super(Person,self).save()

我的假设是在我的模型中写一个def delete(),如下所示:

def delete(self):
    self.party.delete()
    self.delete()

还有一个像这样的管理操作:

class PersonAdmin(admin.ModelAdmin):
    list_display = ('lastName','firstName')
    search_fields = ('firstName', 'lastName')
        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"

这会删除 person.party 和 most of person,但会引发错误,因为 person 的派对 OneToOneField 现在为空。具体错误是:

“/admin/common/person/ 处的断言错误 无法删除派对对象,因为它的 id 属性设置为 None。”

有什么想法吗? Thisthisthis 问题是相关的,但其中只有一个使用了 OneToOneField,而他这样做是错误的。

【问题讨论】:

    标签: sql django admin


    【解决方案1】:

    我感觉它应该像切换删除两者的顺序一样简单(除非你已经尝试过)。由于此人与聚会相关联,一旦您删除个人,您将无法访问聚会。因此你应该这样做

    person.party.delete()
    person.delete()
    

    【讨论】:

    • 谢谢,@Priyeshj。接得好。但是,仍然无法使用该编辑。
    【解决方案2】:

    清理干净并开始工作!

    我的模特:

    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):
            d = self.party.id
            Party.objects.get(id__exact=d).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"
            ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-27
      • 1970-01-01
      • 1970-01-01
      • 2014-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多