2012-02-20 12 views
5

stworzyłem UserProfile (rozciąga się od użytkownika) i zapisywane settings.pyusunąć użytkownika podczas usuwania UserProfile

AUTH_PROFILE_MODULE = 'mainapp.UserProfile'. 

Gdy usunę UserProfile (od obszaru administracyjnego) Chciałbym usunąć również User element.

Próbuję usunąć użytkownika tak, aby self.user.delete(), ale metoda delete (w UserProfile) nie wywołuje. Czemu ?

To jest mój kod:

class UserProfile(models.Model): 
    avatar = models.ImageField(upload_to = settings.PATH_AVATARS, blank=True) 
    url = models.URLField(blank=True) 
    user = models.OneToOneField(User) 

    def __unicode__(self): 
     return self.user.username 

    def delete(self, *args, **kwargs): 
     self.user.delete() 
     super(UserProfile, self).delete(*args, **kwargs) 

Odpowiedz

11

Po pierwsze, aby odpowiedzieć dlaczego "delete()" nie jest wywoływana z admin. To stwierdzenie jest:

  1. prawda w przypadku usuwania obiektów z widoku listy, tj./Admin/auth/user/sprawdzić niektóre okna kliknij przycisk Operacje -> usuń), to dlatego, że delete() metoda z queryset nazywa,
  2. źle w przypadku usunięcia obiektu z change_form , tj./Admin/auth/user/1/kliknij Delete, to gdzie delete() Sposób obiektu nazywa

powiedział, że _delete signals są dobrze obsługiwane. Oto w jaki sposób można go używać:

from django.db.models import signals 

def delete_user(sender, instance=None, **kwargs): 
    try: 
     instance.user 
    except User.DoesNotExist: 
     pass 
    else: 
     instance.user.delete() 
signals.post_delete.connect(delete_user, sender=UserProfile) 

To jak ja testowałem to:

In [1]: from django.contrib.auth.models import User; from testapp.models import UserProfile; User.objects.all().delete(); UserProfile.objects.all().delete() 

In [2]: user=User(username='foo'); user.save() 

In [3]: profile=UserProfile(user=user); profile.save() 

In [4]: UserProfile.objects.all().delete() 

In [5]: User.objects.all() 
Out[5]: [] 

Oczywiście, działa to również gdy delete() metoda obiektu nazywa się:

In [1]: from django.contrib.auth.models import User; from testapp.models import UserProfile; User.objects.all().delete(); UserProfile.objects.all().delete() 

In [2]: user=User(username='foo'); user.save() 

In [3]: profile=UserProfile(user=user); profile.save() 

In [4]: profile.delete() 

In [5]: User.objects.all() 
Out[5]: [] 

Należy pamiętać, że ze względu na cascade delete, to działa w obie strony:

In [1]: from django.contrib.auth.models import User; from testapp.models import UserProfile; User.objects.all().delete(); UserProfile.objects.all().delete() 

In [2]: user=User(username='foo'); user.save() 

In [3]: profile=UserProfile(user=user); profile.save() 

In [4]: user.delete() 

In [5]: User.objects.all() 
Out[5]: [] 

In [6]: UserProfile.objects.all() 
Out[6]: [] 

Aby uzyskać więcej informacji na temat sygnałów, patrz Django's extensive documentation.

+0

Dzięki, że działa. Ale teraz mam kolejne kłopoty. Kiedy napisany signals.post_delete.connect (delete_user, nadawca = UserProfile) muszę również napisać z mainapp.models importować UserProfile i kiedy zarejestrować - mówi błąd IntegrityError w/Konta/Rejestracja/ duplikat klucza wartość narusza ograniczenie wyjątkowe "główny_program_użytkownika_użytkownika_użytkownika" – yAnTar

+0

Czy można otworzyć inny temat i podać więcej szczegółów (kod)? Nie rozumiem twojego komentarza bardzo dobrze ... Z góry dzięki – jpic

+0

Przepraszam, wszystko jest w porządku, przenoszę sygnały z pliku view.py do pliku signals.py i działa dobrze. – yAnTar

Powiązane problemy