Переопределение обратного поиска 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()
Другие вопросы по тегам