如何在同一基于类的视图中使用django_tables2定义两个或多个表

时间:2019-04-26 12:38:25

标签: django-filter django-tables2

我尝试使用django_tables2的MultiTableMixin在基于类的视图中定义两个不同的表。

这些表引用的是同一模型。

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

如何才能定义视图(尤其是表列表)以实现MultiTableMixin?

此源链接无济于事 https://django-tables2.readthedocs.io/en/latest/pages/generic-mixins.html

2 个答案:

答案 0 :(得分:2)

django_tables2确实具有MultiTableMixin以添加多个表。创建一个MultiTableMixin CBV,然后从不同的模型进行queryset并将其存储为变量。从tables.py中的表列表中添加表,并向该表调用相应的queryset变量。以后在模板中的body内部使用for循环呈现表。

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>

答案 1 :(得分:0)

在定义两个表并动态过滤查询集时,我遇到了类似的问题。 我通过重写get_context_data方法来做到这一点,那样我就不必在定义表时提供数据了。 这可能不是最好的方法,但可能会有所帮助。

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

文档说明:

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.