Get request.user in Page and Table views
Closed this issue · 4 comments
Thanks for developing this very useful package. It would be great if you could help with a use case that I am trying to solve.
Briefly, I have a Page
view - something like:
class ReviewPage(Page):
table_1 = Table1()
table_2 = Table2()
where table_1
and table_2
are EditTable
s that load different query sets from the same model, i.e
class Table1(EditTable):
class Meta:
auto__model = myModel
rows = myModel.objects.filter(approved=False)
class Table2(EditTable):
class Meta:
auto__model = myModel
rows = myModel.objects.filter(approved=True)
The issue I am trying to solve for is to add a request.user
based filter on the querysets above. To do this I can wrap the ReviewPage
in a view wrapper, i.e.
def reviewpage_view(request):
context = {'username': request.user}
return ReviewPage(context=context)
But I am not sure how to ensure the request info gets passed on to the Tables, so I can do
class Table1(EditTable):
class Meta:
auto__model = myModel
rows = myModel.objects.filter(approved=False, user__username=username)
I have tried a self.get_request()
on the Table classes and that is null.
Do you have any suggestions on how to achieve this?
Thanks
Trying to fetch the request in the table definition would mean that the code tries to get the request at import time, which of course can't work as you say. You need to pass a function:
class Table1(EditTable):
class Meta:
auto__model = myModel
rows = lambda user, **_: myModel.objects.filter(approved=False, user=user)
This is a general pattern and there's a lot of useful things passed into these lambdas. You can easily find out which things are passed by writing some garbage as a parameter name (like asdasdasd
), where you will get a nice error message with all the options.
Thanks; that is clear now. I ended up needing to do something a little more complicated with the query set, so I wrapped that up in a method called below, i.e.
def get_queryset(username):
# do complex queryset filterting and collect instances
return queryset
class Table1(EditTable):
class Meta:
auto__model = myModel
rows = lambda user, **_: get_queryset(user)
You could simplify that a bit more:
def get_queryset(user, **_):
# do complex queryset filterting and collect instances
return queryset
class Table1(EditTable):
class Meta:
auto__model = myModel
rows = get_queryset
You don't need the lambda, if you just add **
to the signature of the function.
Or even:
class Table1(EditTable):
class Meta:
auto__model = myModel
@staticmethod
def rows(user, **_):
# do complex queryset filterting and collect instances
return queryset = get_queryset