Переопределение обратного поиска django один к одному
Нужна помощь с обратным поиском один на один. Мои модели:
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. Есть идеи?
2 ответа
Технически запись существует так перезаписывает 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")
Это отношение один к одному, и основным объектом является экземпляр User, а не экземпляр UserProfile. Другими словами, user
это то, что использовалось в большей части кода. Например, в представлении вы используете request.user
,
Я не уверен, что профиль с мягким удалением подразумевает в вашем приложении, но давайте представим, что это означает, что он не является общедоступным. В этом случае я бы сохранил это в User
:
class User(MarkedAsDeletedMixin):
is_profile_public = models.BooleanField(default=True)
Да, вы можете использовать менеджер, вам просто нужно изменить 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()