2012-02-24 5 views
1

다른 모델을 OneToOneField을 통해 참조하는 모델이 있으므로 Django에 내장 된 delete_selected admin 작업을 사용하면 연결된 모델의 데이터가 삭제되지 않습니다. 해당 모델의 데이터를 삭제하는 사용자 지정 관리자 작업을 작성하고 싶습니다.admin에서 연결된 OneToOneField 모델의 SQL 데이터 삭제

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(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와 대부분의 사람을 삭제하지만 사람의 파티 때문에 오류가 발생합니다 OneToOneFi 필드가 비어 있습니다. 특정 오류는 다음과 같습니다.

"admin/common/person/ id 속성이 None으로 설정되어 있으므로 Party 객체를 삭제할 수 없습니다."

아이디어가 있으십니까? This, thisthis 질문은 관련이 있지만 그 중 하나만 OneToOneField를 사용하고 잘못했음을 나타냅니다.

답변

1

정리하고 작동했습니다!

내 모델 :

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

두 가지를 삭제하는 순서를 전환하는 것만 큼 간단해야한다는 생각이 들었습니다 (이미 시도한 경우 제외). 사람이 파티와 연관되어 있으므로 사람을 삭제하면 파티에 액세스 할 수 없습니다. 그러므로해야 할 일

person.party.delete() 
person.delete() 
+0

감사합니다, @Priyeshj. 좋은 캐치. 그러나 아직 그 편집 작업을하지는 않습니다. – reK1NDLE