Home > database >  Override a specific argument in all django model queries?
Override a specific argument in all django model queries?

Time:03-01

I have a custom django user model that does not contain a username field, it uses email instead. I am attempting to implement a 3rd party package that makes queries to the user model based on username. Is there a way to override all queries (get, filter, etc.) to this model through a custom manager or otherwise so that username is simply converted to email?

It would turn this:

User.objects.filter(username="[email protected]")

into

User.objects.filter(email="[email protected]")

CodePudding user response:

You can create a QuerySet subclass where you "clean" the incoming kwargs for the get and filter methods and change username to email

class UserQuerySet(models.QuerySet):

    def _clean_kwargs(self, kwargs):
        if 'username' in kwargs:
            kwargs['email'] = kwargs['username']
            del kwargs['username']
        return kwargs

    def filter(self, *args, **kwargs):
        kwargs = self._clean_kwargs(kwargs)
        return super().filter(*args, **kwargs)

    def get(self, *args, **kwargs):
        kwargs = self._clean_kwargs(kwargs)
        return super().get(*args, **kwargs)


class UserManager(BaseUserManager):

    def get_queryset(self):
        return UserQuerySet(self.model, using=self._db)


class User(AbstractBaseUser):
    
    objects = UserManager()

The custom manager will need to implement create_user and create_superuser as detailed here in the docs

  • Related