sqlalchemyとの違いにハマったのでメモ。
以下のようなモデルを前提にする。
class User(models.Model):
name = models.CharField(max_length=255, null=False, default="")
class UserProfile(models.Model):
score = models.IntegerField(null=False, default=0)
user = models.OneToOneField(User, related_name="profile")
UserとUserProfileが定義されていて。それらは1:1の関係になっている。
ここで以下のようにpropertyアクセスすることで関連するオブジェクトを取得できる。
user = User.objects.get(id=1)
user.profile # <UserProfile>
profile = UserProfile.objects.get(id=1)
profile.user # <User>
また、保存する時には途中でsaveしてあげる必要がある。
user = User()
user.save()
profile = UserProfile(user=user)
profile.save()
以下はエラーになることに注意
UserProfile().save()
理由は、テーブルのuser_idがnullになってしまうから。not null制約に引っかかるため。(OneToOneFieldを指定したクラスの変数に対応するフィールドにidが付加されるので、ここではuser_idがuserprofileテーブルに存在。テーブル上はforeignkey+unique constraint)
また以下の様なことができない。
User(profile=profile)
related_nameはあくまで関連をたどることが可能なプロパティを生やすものであって、双方向に結びつくような特殊なカラムを抽象化した何かというわけではない。(一方sqlalchemyはrelated_nameに似た設定値をコンストラクタの引数として利用可能)
参考