Search code examples
pythondjangodjango-modelsdjango-managers

django - dynamic manager



I have a model that has an owner field.

class MyModel(models.Model):
    owner = models.CharField(...)

I extended the django User class and added an ownership filed

class AppUser(User):
    ownership = models.CharField(...)

I want to create a Manager for MyModel so it will retrieve only objects that correspond with ownership of the currently logged in user.
For example (using Django REST framework):

class MyModelAPI(APIView):
    def get(self, request, format=None):
        # This query will automatically add a filter of owner=request.user.ownership
        objs = MyModel.objects.all()
        # rest of code ...

All of the examples of managers user constant values in their queries and i'm looking for something more dynamic. Is this thing even possible?
Thanks


Solution

  • This is not possible with a custom manager because a model manager is instantiated at class loading time. Hence, it is stateless with regard to the http-request-response cycle and could only provide some custom method that you would have to pass the user to anyway. So why don't you just add some convenience method/property on your model (a manager seems unnecessary for this sole purpose)

    class MyModel(models.Model):
        ...
        @clsmethod
        def user_objects(cls, user):
            return cls.objects.filter(owner=user.ownership)
    

    Then, in your view:

    objs = MyModel.user_objects(request.user)
    

    For a manager-based solution, look at this question. Another interesting solution is a custom middleware that makes the current user available via some function/module attribute which can be accessed in acustom manager's get_queryset() method, as described here.