Удаление данных SQL в связанной модели OneToOneField от администратора - PullRequest
1 голос
/ 25 февраля 2012

У меня есть модель, которая ссылается на другую модель через 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 и большую часть лица, но выдает ошибку, потому что сторона участника OneToOneField теперь пуста. Конкретная ошибка:

"AssertionError at / admin / common / person / Невозможно удалить объект Party, поскольку его атрибут id имеет значение None. "

Есть идеи? Этот , , этот и этот вопрос связаны, но только один из них использует OneToOneField, и он сделал это по ошибке.

Ответы [ 2 ]

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

Вычистил и работает!

Моя модель:

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"
        ...
1 голос
/ 25 февраля 2012

У меня возникает ощущение, что это должно быть так же просто, как переключить последовательность удаления двух (если вы уже не попробовали это). Поскольку человек связан с вечеринкой, после его удаления вы не сможете получить доступ к вечеринке. Следовательно, вы должны сделать

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