gtopal
gtopal

Reputation: 594

How to define in the same class based view two or more tables with django_tables2

I am trying unsuccessfully to define two different tables in my class based view with MultiTableMixin of django_tables2.

The tables are refering to the same model.

tables.py

class PrescriptionsTable(tables.Table):
class Meta:
        #define the model
        model = Prescription
        template_name = 'django_tables2/bootstrap4.html'
        sequence = ("id", "patient","status")

class PrescriptionsTable2(tables.Table):
class Meta:
        #define the model
        model = Prescription
        template_name = 'django_tables2/bootstrap4.html'
        sequence = ("id", "patient","status")

filters.py

class PrescriptionFilter(django_filters.FilterSet):
        patient = django_filters.CharFilter(lookup_expr='icontains')


        class Meta:
            model = Prescription
            fields = ['id','patient','status']

views.py

class PrescriptionListView(LoginRequiredMixin,MultiTableMixin, TemplateView):
    template_name='prescriptions/prescription_list2.html'
    tables = []
    filterset_class = PrescriptionFilter

    def get_context_data(self, **kwargs):
        context = super(PrescriptionListView, self).get_context_data(**kwargs)
        table=Prescription.objects.filter(created__gte=date(2018, 10, 1))
        context['table'] =table
        has_filter = any(field in self.request.GET for field in set(self.filterset_class.get_fields()))
        context['has_filter'] = has_filter
        return context

How can I have to define my view and more in particular the tables list in order to manage to achieve MultiTableMixin?

This source link did not help https://django-tables2.readthedocs.io/en/latest/pages/generic-mixins.html

Upvotes: 2

Views: 1475

Answers (2)

czerpi
czerpi

Reputation: 61

I had similar problem with defining two tables and filtering querysets dynamically. I managed to do this by overriding get_context_data method.In that way I don't have to provide data while defining tables. It's probably not the best method, but may be helpful.

from .models import model1,model2
from django.shortcuts import render
from django_tables2 import RequestConfig
from django_tables2.views import MultiTableMixin
from itertools import count

**views.py**

class PersonTablesView(MultiTableMixin):    
    template_name = 'data/data.html'    

    # qs = model1.objects.all()
    # qs1 = model2.objects.all()
    # tables = [
    #     TrackTable(qs),
    #     OTNPHTable(qs1)
    # ]

    table_pagination = {
        'per_page': 10
    }


    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # do something with your querysets
        qs = model1.objects.all()
        qs1 = model2.objects.all()
        tables = [
          TrackTable(qs), 
          OTNPHTable(qs1)
        ]

        # apply prefixes and execute requestConfig for each table
        table_counter = count()
        for table in tables:
            table.prefix = table.prefix or self.table_prefix.format(
                next(table_counter))

            RequestConfig(self.request, paginate=self.get_table_pagination(
                table)).configure(table)

            context[self.get_context_table_name(table)] = list(tables)

        return context

Documentation suggets:

The `tables` attribute must be either a list of `.Table` instances or
classes extended from `.Table` which are not already instantiated. In that
case, `get_tables_data` must be able to return the tables data, either by
having an entry containing the data for each table in `tables`, or by
overriding this method in order to return this data.

Upvotes: 0

Viswanathan L
Viswanathan L

Reputation: 193

django_tables2 do have MultiTableMixin to add more than one table. Create a MultiTableMixin CBV, then do queryset from different models and store it as variable. Add tables from tables.py inside tables list and call the correponding queryset variable to that tables.Later use for loop inside body in template to render the tables.

from .models import model1,model2
from django.shortcuts import render
from django_tables2 import RequestConfig
from django_tables2.views import MultiTableMixin

**views.py**

class PersonTablesView(MultiTableMixin):    
    template_name = 'data/data.html'    

    qs = model1.objects.all()
    qs1 = model2.objects.all()
    tables = [
        TrackTable(qs),
        OTNPHTable(qs1)
    ]

    table_pagination = {
        'per_page': 10
    }

**data.html**

{# data/data1.html #}
{% load render_table from django_tables2 %}
{% load bootstrap4 %}
<!doctype html>
<html>
    <head>
        <title>List of persons</title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
    </head>
    <body>
        {% for table in tables %}
            {% render_table table 'django_tables2/bootstrap.html' %}
        {% endfor %}
    </body>
</html>

Upvotes: 3

Related Questions