Search code examples
djangodjango-tables2

Django-tables2 - self.request in render


I am trying to change the table view based on the username of requests, but it keeps returning the AttributeError for the table object has no attribute 'request.' I have directly added the request to the table (please refer below for codes), but still not able to get it done. In my table class, I have the "get_top_pinned_data" overridden to fetch the data from the database based on the username.

views.py

class ListView(LoginRequiredMixin, ExportMixin, SingleTableView):
    ...
    def get_context_data(self, **kwargs):
        context = super(ListView, self).get_context_data(**kwargs)
        table = self.get_table(**self.get_table_kwargs())
        table.request = self.request        # ADDING REQUEST DIRECTLY TO TABLE
        context[self.context_filter_name] = self.filter
        context['firstname'] = str(self.request.user.first_name)
        return context

    def get_table(self, **kwargs):
        table_class = self.get_table_class()
        table = table_class(data=self.get_table_data(), **kwargs)
        return RequestConfig(self.request, paginate={'per_page':self.paginate_by}).configure(
            table
        )

tables.py

class Table(tables.Table):
    ...
    def get_top_pinned_data(self):
        id_list = MODEL.objects.filter(USERNAME=self.request.user.username).values_list('id', flat=True)
        pinned = MODEL.objects.filter(id__in=id_list)
        return pinned

Can anyone please help me out?


**EDIT: adding request to table in get_table function

views.py

class ListView(LoginRequiredMixin, ExportMixin, SingleTableView):
    ...
    def get_context_data(self, **kwargs):
        context = super(ListView, self).get_context_data(**kwargs)
        context[self.context_filter_name] = self.filter
        context['firstname'] = str(self.request.user.first_name)
        return context

    def get_table(self, **kwargs):
        table_class = self.get_table_class()
        table = table_class(data=self.get_table_data(), **kwargs)
        table.request = self.request
        return RequestConfig(self.request, paginate={'per_page':self.paginate_by}).configure(
            table
        )

Solution

  • I find it cleaner to put table.request inside of get_table instead,

    def get_table(self, **kwargs):
        """
        Return a table object to use. The table has automatic support for
        sorting and pagination.
        """
        table_class = self.get_table_class()
        table = table_class(data=self.get_table_data(), **kwargs)
        table.request = self.request
        return RequestConfig(
            self.request, paginate=self.get_table_pagination(table)
        ).configure(table)
    

    If you still experience AttributeError, request is used before its set in get_table, a potential solution would be the following:

    def get_table(self, **kwargs):
        """
        Return a table object to use. The table has automatic support for
        sorting and pagination.
        """
        table_class = self.get_table_class()
        table = table_class(data=self.get_table_data(), request=self.request, **kwargs)
        table.request = self.request
        return RequestConfig(
            self.request, paginate=self.get_table_pagination(table)
        ).configure(table)
    

    And get the request object from your Tables init method like:

    class Table(tables.Table):
        def __init__(self, *args, **kwargs):
            self.request = kwargs.pop("request")
            super().__init__(*args, **kwargs)
    
        def get_top_pinned_data(self):
            id_list = MODEL.objects.filter(USERNAME=self.request.user.username).values_list('id', flat=True)
            pinned = MODEL.objects.filter(id__in=id_list)
            return pinned