2017-07-09 20 views
0

私は教育会社向けのdjangoアプリケーションを作成しています。カスタムモデルと、ユーザーモデルから継承するカスタムクラスと2つのクラス(StudentとTeacher)を作成しました。 1対1の関係。Djangoオーバーライドされた保存関数は親フィールドを保存しません

先生と学生の両方が同じユーザーオブジェクトを使用する状況を避けようとしています。したがって、私はUserオブジェクト内にuser_type charフィールドを持っています。ユーザーが先生に設定されていると、フィールドが更新されます。その後、ユーザーを学生にしようとすると、エラーが発生します。

clean()関数がsave()関数で呼び出された後、user_typeが更新されたようですが、実際にテストすると、user_typeが返されているようです空の文字列。私は誰かが私に正しい方向を指すことができるかどうか疑問に思います。

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') 

答えて

2

あなたはTeacher例えば、ないUserインスタンスを保存しています。 user_typeを割り当てるときは、Userインスタンスに対してsave(..)を実行する必要があります。レコードは魔法のように更新されません。

他の言い方をすれば、インスタンス属性を変更していますが、インスタンスは保存していません。

+0

ありがとうございました!したがって、super.save()は実際に親を保存しません。スーパーは親を参照していないのですか?これはself.user.save()とは異なりますか?申し訳ありませんが、Djangoにはとても新しいです –

+0

Djangoの知識の問題ではありません。あなたの親クラスは 'User'ではありません。あなたの親クラスは 'TimeStampedModel'と呼ばれるモデルで、' save'は呼び出されたモデルです。 'user'属性はそれとは関係ありません。 ['super()'](https://docs.python.org/3/library/functions.html#super)がどのような目的で使用されているかを確認する必要があります。 – RompePC

+0

ああ、あなたは正しい - 私はそのユーザーが親クラスではなく属性であることを忘れていた。それを指摘してくれてありがとう。 –

関連する問題