Пользовательское удаление модели и связанной модели через OneToOneField - PullRequest
1 голос
/ 29 февраля 2012

Я перезаписываю действия администратора Django delete_selected. У меня есть модель (Person), связанная с другой моделью (Party) через OneToOneField, и delete_selected удаляет только исходную модель, а не данные из связанной модели, оставляя меня с «призрачными строками» в моей базе данных , Похоже, это само по себе может указывать на проблемы в моем коде, так как я предполагаю, что функция delete() будет каскадно удалять и связанную модель.

В любом случае, проблема в том, что моя пользовательская функция delete() сначала удаляет Party, а затем OneToOneField 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"
    ...

Ошибка:

AssertionError at /admin/common/person/ 
Party object can't be deleted because its id attribute is set to None.

Ответы [ 2 ]

1 голос
/ 01 марта 2012

Я не уверен, почему это работает, но это работает ...

Я изменил функцию delete() моей модели на:

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

Я думаю, это, по сути, делает то, что@Furbeenator предложил, удалив правильную строку в Party, что каскад также удалил правильную строку в Person.Три ура за случайные снимки в темноте, которые иногда работают, а?

0 голосов
/ 29 февраля 2012

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