2016-07-11 5 views
0

Нужна помощь с одним обратным поиском. Мои модели:django один к одному обратный поиск override

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

Вы можете видеть, что я переопределение метода delete так, когда я someuser.userprofile.delete() я просто пометить объект Userprofile как удаленные.

Проблема возникает если сделаю someuser.userprofile после. Я получаю userprofile, потому что я не удалял userprofile, я просто пометил его как удаленный.

Чтобы получить только объекты userprofile, не помеченные как удаленные, мне нужно переопределить один обратный поиск User или сделать что-то с менеджером 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") 

Это отношение один к одному, а основной объект является экземпляром пользователя, а не экземпляр 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()