1


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

Mr T.
  • 4,278
  • 9
  • 44
  • 61

1 Answers1

2

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.

Community
  • 1
  • 1
user2390182
  • 72,016
  • 6
  • 67
  • 89
  • Thanks. The problem with this approach is that im using Django REST framework so if i have a ListAPIView, i cant really set the correct queryset `queryset = MyModel.objects.owned_by()` – Mr T. May 17 '16 at 12:47
  • 1
    Actually this is possible and is very useful when testing. You can add manager dynamically by calling `MyModel.add_to_class("mycustommanager", Manager())` – MartinM Aug 01 '18 at 11:32
  • You can access the request in `get_queryset`: https://www.django-rest-framework.org/api-guide/generic-views/#get_querysetself – DylanYoung Aug 25 '20 at 17:05