3

I have a model manager with a get_queryset:

class BookManager(models.Manager):

    def get_queryset(self):

        return super().get_queryset().filter(author=self.request.user

This results in the error:

AttributeError: 'BookManager' object has no attribute 'request`

I understand managers are "request-unaware". How would I make a method in your manager/queryset that takes a parameter for the request.user?

alias51
  • 8,178
  • 22
  • 94
  • 166
  • 1
    What if there's no request? There can be many situations where there is no request when using the manager (e.g. management commands, periodic tasks to clean up things, ...). This sounds like an XY problem. Why do you want to filter on a specific user in the manager's default queryset? What are you trying to achieve in the first place? – dirkgroten Jan 08 '20 at 15:34
  • 2
    You can create a new method on your BookManager that accepts an extra parameter (but not `get_queryset()` as that's the default.). e.g. `def by_author(self, user): return self.get_queryset().filter(author=user)` and then in a view `Book.objects.by_author(request.user)`. But I don't know whether that would achieve what you want. – dirkgroten Jan 08 '20 at 15:37

2 Answers2

11

Short answer: The request object is only available in a view, so you can't assume it's available in your model manager.

Pass it from your view to a method in your manager that accepts it:

class BookManager(models.Manager):
    def by_author(self, user):
        return self.get_queryset().filter(author=user)

Then in your view you can do Book.objects.by_author(request.user). You'd need to make sure first that request.user is a logged in user otherwise you'll get an exception.

Note: In this particular case I wouldn't go through the trouble of defining by_author since it hardly makes your code more readable. But if there are more complex queries that you often need, then it might make sense to assign them a method in your manager to create DRY code.

dirkgroten
  • 20,112
  • 2
  • 29
  • 42
0

If the user is the current user you can use threads. You can set it in the authentication class and retrieve it

McMazalf
  • 59
  • 1
  • 9