2017-07-09 7 views
0

Ich erstelle eine Django - App für ein Bildungsunternehmen, und ich habe ein benutzerdefiniertes Benutzermodell und zwei Klassen (Student und Teacher) erstellt, die vom Benutzermodell über eine Eins-zu-eins-Beziehung.Django - überschriebene Speicherfunktion speichert keine übergeordneten Felder

Ich versuche die Situation zu vermeiden, in der ein Lehrer und ein Schüler beide das gleiche Benutzerobjekt verwenden. Daher habe ich in meinem Benutzerobjekt ein char_feld user_type, und wenn ein Benutzer als Lehrer eingestellt ist, wird das Feld aktualisiert. Wenn ich dann versuche, den Benutzer zum Schüler zu machen, sollte es einen Fehler auslösen.

Ich versuche, die Überprüfung in der clean-Funktion zu tun - nachdem die clean() -Funktion in der Funktion save() aufgerufen wird, scheint der user_type aktualisiert zu sein, aber wenn ich tatsächlich teste, scheint user_type zurückzukehren eine leere Zeichenfolge. Ich frage mich, ob mir jemand die richtige Richtung zeigen könnte.

class User(AbstractUser):  
    user_type = models.CharField(max_length=20, choices=USER_TYPES, blank=True) 

class Teacher(TimeStampedModel): 
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) 

    def clean(self): 
     if self.user.user_type and self.user.user_type !='teacher': 
      raise ValidationError('Some error') 
     else: 
      self.user.user_type = 'teacher' 

    def save(self, *args, **kwargs): 
     self.clean() 
     #this prints 'teacher' 
     print(self.user.user_type) 
     super().save(*args, **kwargs) 

tests.py 
#this test fails 
def test_should_set_user_type_automatically_to_teacher(self): 
    user = User.objects.create(username='tangbj', first_name='Dan') 
    Teacher.objects.create(user=user)   
    teacher = Teacher.objects.get(user__username='tangbj') 

    print(teacher.user.user_type) 
    self.assertEqual(teacher.user.user_type, 'teacher') 

Antwort

2

Sie sparen die Teacher Beispiel nicht die User Instanz. Wenn Sie die user_type zuweisen, sollten Sie eine save(..) an die User Instanz ausführen. Aufzeichnungen werden nicht magisch aktualisiert.

In anderer Weise gesagt; Sie ändern ein Instanzattribut, aber Sie speichern die Instanz nicht.

+0

Vielen Dank! So speichert super.save() nicht wirklich das Elternteil. Bezieht sich super nicht auf das Elternteil? Und das ist anders als self.user.save()? Entschuldigung, sehr neu zu Django –

+0

Ist kein Problem von Django Wissen; Tatsache ist, dass Ihre Elternklasse nicht "Benutzer" ist. Ihre Elternklasse ist ein Modell mit dem Namen "TimeStampedModel", und ihr 'save' ist derjenige, der angerufen wird. Das Attribut 'user' hat damit nichts zu tun. Sie sollten überprüfen, was ['super()'] (https://docs.python.org/3/library/functions.html#super) verwendet wird. – RompePC

+0

Oh Dang, du hast Recht - ich habe vergessen, dass Benutzer ein Attribut und nicht die Elternklasse war. Danke, dass du darauf hingewiesen hast. –