2016-07-11 16 views
0

1対1リバースルックアップのヘルプが必要です。私のモデル:django 1対1リバースルックアップオーバーライド

class User(MarkedAsDeletedMixin): 
    fields here 

class UserProfile(MarkedAsDeletedMixin): 
    user = models.OneToOneField(User) 

class MarkedAsDeletedMixin(models.Model): 
    marked_as_deleted = models.BooleanField(default=False) 

    class Meta: 
     abstract = True 

    def delete(self, *args, **kwargs): 
     self.marked_as_deleted = True 
     self.save() 

あなたが削除されたものとして、私はsomeuser.userprofile.delete()私はUSERPROFILEオブジェクトをマークしないとき、私はそうdeleteメソッドをオーバーライドしています見ることができます。

私がsomeuser.userprofileの後に問題が発生します。 userprofileを削除しなかったので、私はuserprofileを取得しました。私はそれを削除済みとしてマークしました。

削除済みとマークされていないuserprofileオブジェクトだけを取得するには、Userの1対1逆引き参照を上書きするか、UserProfileのマネージャで何かを行う必要があります。何か案は?

答えて

0

技術的には、レコードが存在するので、それを隠すために上書きするuser.profileは意味をなさないでしょう。それはコードを理解しにくくするでしょう。

あなたが代わりにメソッドを追加することができます。

class User(MarkedAsDeletedMixin): 
    def get_profile(): 
     return self.profile if self.profile and not self.profile.marked_as_deleted else None 

class UserProfile(MarkedAsDeletedMixin): 
    user = models.OneToOneField(User, related_name="profile") 

これは1対1の関係で、主なエンティティはUserインスタンス、ないのUserProfileインスタンスです。言い換えれば、userはほとんどのコードで使用されているものです。たとえば、ビューではrequest.userを使用します。

ソフト削除されたプロファイルがアプリケーションに何を意味するのかよく分かりませんが、公開されていないということを想像してみましょう。その場合、私はUserでこれを救う:

class User(MarkedAsDeletedMixin): 
    is_profile_public = models.BooleanField(default=True) 
0

はい、あなたはマネージャーを使用することができ、あなただけのget_querysetを変更する必要があると思います。どのサブクラスにも継承されるべきであるMarkedAsDeletedMixinのマネージャにこれを置くのが最善でしょう。このようなもの:

from django.db import models 

class MarkedAsDeletedManager(models.Manager): 

    use_for_related_fields = True 

    def get_queryset(self): 
     return self.filter(marked_as_deleted=False) 

class MarkedAsDeletedMixin(models.Model): 
    marked_as_deleted = models.BooleanField(default=False) 
    objects = MarkedAsDeletedManager() 

    class Meta: 
     abstract = True 

    def delete(self, *args, **kwargs): 
     self.marked_as_deleted = True 
     self.save()