2016-07-11 1 views
0

Besoin d'aide pour une recherche inversée un à un. Mes modèles:Remplacement de recherche inversée django un à un

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

Vous pouvez voir que je suis redéfinissant la méthode delete quand je fais someuser.userprofile.delete() je marque tout l'objet userprofile comme supprimé. Le problème vient quand je fais someuser.userprofile après. Je deviens userprofile, parce que je n'ai pas supprimé le profil utilisateur, je l'ai juste marqué comme supprimé. Pour que seuls les objets du profil utilisateur ne soient pas marqués comme supprimés, je dois redéfinir la recherche inversée un à un de User ou faire quelque chose avec le gestionnaire du UserProfile. Des idées?

Répondre

0

Techniquement, l'enregistrement existe en écrasant user.profile pour le masquer n'aurait aucun sens. Cela rendrait le code plus difficile à comprendre.

Vous pouvez ajouter une méthode à la place:

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

C'est une relation biunivoque et l'entité principale est l'instance de l'utilisateur, et non pas l'instance UserProfile. En d'autres termes, le user est ce qui a été utilisé dans la majeure partie du code. Par exemple, dans une vue, vous utilisez request.user.

Je ne suis pas sûr de ce que le profil soft-deleted implique dans votre application, mais supposons que cela signifie que ce n'est pas public. Dans ce cas, je sauverais cela dans le User:

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

Oui, vous pouvez utiliser un gestionnaire, vous auriez tout simplement de modifier get_queryset. Il est probablement préférable de mettre ceci sur un gestionnaire pour le MarkedAsDeletedMixin - qui devrait être hérité par n'importe quelle sous-classe. Quelque chose comme ceci:

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