Python Django Best Practice for request.user in Class Based Views and Queryset

Viewed 594

I am using class based views and have always the same problem without an elegant solution. My querysets should only show the ones that are owned of the request user.

Code

view:

class MyListView(ListView):
    model = MyModel

    def get_queryset(self):
        return self.model.objects.owned_by_user(self.user)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.user = None

    def dispatch(self, request, *args, **kwargs):
        self.user = request.user

        return super().dispatch(request, *args, **kwargs)

model:

class MyModelQuerySet(models.QuerySet):
    def owned_by_user(self, user):
        return self.filter(user_field=user)


class MyModelManager(models.Manager):
    def get_queryset(self):
        return MyModelQuerySet(self.model, using=self._db)

    def owned_by_user(self, user):
        return self.get_queryset().owned_by_user(user)


class MyModel(models.Model):
    user_field = ...

    objects = ProductRequestManager()

Best practice 1:

I think I have to overwrite dispatch to add the request.user. My IDE notes "Instance attribute user defined outside of init. In order to prevent this I also need to overwrite init(). How can I achieve this with less code?

Best practice 2:

Is there another way to get querysets belonging to the current user?

1 Answers

You just filter the queryset with self.request.user. Note that the setup() method will assign values to self.request, self.args, and self.kwargs:

class MyListView(ListView):
    model = MyModel

    def get_queryset(self):
        return self.model.objects.owned_by_user(self.request.user)

Note: You can limit views to a class-based view to authenticated users with the LoginRequiredMixin mixin [Django-doc].

Related