【问题标题】:How do I fitler the intial table using django-tables2 and django-filter?如何使用 django-tables2 和 django-filter 过滤初始表?
【发布时间】:2021-03-31 14:20:34
【问题描述】:

我正在使用 django-tables2 和 django-filter 列出模型中的员工。我无法过滤呈现的初始表。它包括所有记录。我希望初始表仅包含 status=1 的员工。然后,让过滤器接管。

views.py

from .models import Employee
from .tables import EmployeeTable
from .filters import EmployeeFilter
from .forms import EmployeeSearchForm

class EmployeeListView(SingleTableMixin, FilterView):
    model = Employee
    table_class = EmployeeTable
    template_name = 'employees/employee_list.html'

    filterset_class = EmployeeFilter

    def get_table_data(self):
        return Employee.objects.filter(status=1)

filters.py:

from django.db.models import Value, Q
from django import forms

from .models import Employee

class EmployeeFilter(django_filters.FilterSet):
    search = django_filters.CharFilter(label='Search', method='search_filter')
    inactive = django_filters.BooleanFilter(widget=forms.CheckboxInput, label='Inactive', method='include_inactive')
    
    def search_filter(self, queryset, name, value):
        return queryset.annotate(fullname=Concat('first_name', Value(' '), 'last_name')).filter(
                Q(fullname__icontains=value) | Q(g_number__icontains=value)
            )

    def include_inactive(self, queryset, name, value):
        expression = Q(status__in=[1,2,5]) if value else Q(status__in=[1,5])
        return queryset.filter(expression)
    
    class Meta:
        model = Employee
        fields = ['search', 'inactive']

tables.py:

from django.utils.html import format_html
from django.urls import reverse

import django_tables2 as tables

from .models import Employee

class EmployeeTable(tables.Table):
    full_name = tables.Column(order_by=("first_name", "last_name"))
    g_number = tables.Column(linkify=True)
    selection = tables.columns.CheckBoxColumn(
            accessor='pk', 
            attrs = { "th__input": {"onclick": "toggle(this)"}},
            orderable=False
        )
    term = tables.Column(verbose_name=("Action"), empty_values=())

    class Meta:
        model = Employee
        
        template_name = "django_tables2/bootstrap.html"
        fields = ("selection", "g_number","full_name", 'org', 'job', 'status', 'term')
        attrs = {
            "class": "table table-hover",
            "thead": {"class": "thead-dark"}
        }
        order_by = '-g_number'

【问题讨论】:

    标签: python django django-filter django-tables2


    【解决方案1】:

    从 Django 过滤器文档中,您可以过滤过滤器类上的主要查询集。更新:要根据 self.request 中的属性设置 qs,只需检查该属性并进行相应的过滤。

    https://django-filter.readthedocs.io/en/master/guide/usage.html#filtering-the-primary-qs

    class EmployeeFilter(django_filters.FilterSet):
    
        [...]       
    
        @property
        def qs(self):
            parent = super().qs
            filter_inactive = getattr(self.request, 'inactive', False)
    
            if not filter_inactive:
                return parent.filter(status=1)
    
            return parent
    

    【讨论】:

    • 这会正确过滤初始表。但是,检查“非活动”过滤器不会像预期的那样包括状态为 2 和 5 的员工。
    • 所以,需要明确的是,您希望初始状态仅为 status=1,然后在任何搜索时:inactive=False/None 返回 status=1,5 并且 inactive=True 返回 status=1,2, 5 ?
    • 是的,这正是我所追求的。谢谢你的帮助!!!
    猜你喜欢
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    • 2019-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多