Django_表2带过滤器的动态列
我们的目标是实现一个简单的视图,让用户通过一些添加的计算信息(某些特定列上的注释)动态选择列,并允许他们对字段进行过滤 感谢您的评论,因为这花了我好几个小时让它正常工作,所以我想我会为任何看到类似问题的人提供一个简短的书面说明:) 使用的模块/库等: Django滤波器 Django_表2 引导选择以正确显示多选字段 我们希望使用的示例模型:Django_表2带过滤器的动态列,django,django-filter,django-tables2,Django,Django Filter,Django Tables2,我们的目标是实现一个简单的视图,让用户通过一些添加的计算信息(某些特定列上的注释)动态选择列,并允许他们对字段进行过滤 感谢您的评论,因为这花了我好几个小时让它正常工作,所以我想我会为任何看到类似问题的人提供一个简短的书面说明:) 使用的模块/库等: Django滤波器 Django_表2 引导选择以正确显示多选字段 我们希望使用的示例模型: class Summary(models.Model): billing_date = models.DateField(verbose_name
class Summary(models.Model):
billing_date = models.DateField(verbose_name='Billing Date')
period = models.CharField(max_length=10, verbose_name='Period')
operator = models.CharField(max_length=50, verbose_name='Operator')
product = models.CharField(max_length=30, verbose_name='Product')
...
过滤器非常简单,这里唯一的特殊情况是我们最初需要一个空的queryset,并且需要一些字段 “info”将保存我们的“Summary”模型的select列,“product”和“operator”只是Summary中的字段
class AdHocReportFilter(django_filters.FilterSet):
info = django_filters.MultipleChoiceFilter(choices=report_field_choices, label='Available Fields', required=True)
product = django_filters.ModelChoiceFilter(queryset=Product.objects.all(), label='Products', required=True)
operator = django_filters.CharFilter(field_name="operator", lookup_expr='contains', label='Operator')
....
def __init__(self, *args, **kwargs):
super(AdHocReportFilter, self).__init__(*args, **kwargs)
if self.data == {}:
self.queryset = self.queryset.none()
模板:
这里没有什么有趣的内容,您可以使用引导选择来整理您的多选择字段(有很多关于它的好文章)。
确保将表放入“如果”,因为对象可能存在,也可能不存在,这取决于您的视图(如果有人想要模板示例,请告诉我)
视图:
相应地提取GET请求(作为列表或简单值,具体取决于可用的筛选器)
实际的筛选器本身取决于您希望用户能够筛选的内容,请确保所有必需的字段都是必需的,或者用一些标准值替换它们,因为筛选器不接受任何类型。
“field__contains”是您在这里的朋友,因为它还将显示未选中字段的值!
特殊情况下,如果特定字段的DB中实际存在“Null”值,请将它们移动到另一个过滤器,如下面的Q查询示例
幸运的是,“values”接受“*list”,这是所有可用列的简单列表。
注释只取决于您想要实现什么
使用添加的参数“user\u columns”调用表对象,该参数保存我们的列表,以便我们可以构建所需的表
@login_required
def ad_hoc_report(request):
template_name = 'non_voice/ad_hoc_report.html'
filter = AdHocReportFilter(request.GET, queryset=Summary.objects.all())
info = request.GET.getlist('info', None)
product = request.GET.get('product', '')
operator = request.GET.get('operator', '')
start_date = request.GET.get('start_date', None)
end_date = request.GET.get('end_date', None)
if operator is None:
operator = ''
result_object = Summary.objects.filter(product__contains=product, ).filter((Q(operator__contains=operator)|Q(operator__isnull=True)).values(*info).annotate(
Amount=Sum("amount"), Count=Sum("count"))
table = AdHocReportTable(data=result_object, user_columns=info)
return render(request, template_name, {'filter': filter, 'table': table})
表:
这是最困难的部分,只有在大量阅读各种堆栈溢出注释的情况下才能做到:)
首先定义计算注释列并设置所需的元信息,“…”是一个内置占位符,事先不知道列名(这有助于我们将计算列移动到表的末尾)
在init中,我们首先检查“self.base_columns”是否与我们提供的内容一致,并删除用户取消选择的列,否则即使在过滤之后,它仍然会显示为空。(也许有更好的方法,我还没找到)
在下一步中,添加用户从上面提到的“user_columns”(我们在views.py中传递)中动态选择的列
class AdHocReportTable(tables.Table):
Amount = tables.Column(verbose_name='Amount')
Count = tables.Column(verbose_name='Count')
class Meta:
# '...' is a built in placeholder!
sequence = ('...', 'Amount', 'Count')
template_name = "django_tables2/bootstrap4.html"
attrs = {'class': 'table table-hover', }
# This makes it possible to pass a dynamic list of columns to the Table Object
def __init__(self, data, user_columns, *args, **kwargs):
if user_columns:
calulated_columns = ['Amount', 'Count']
# Removes deselected columns from the table (otherwise they are shown empty)
for key, val in self.base_columns.items():
if key not in user_columns and key not in calulated_columns:
del self.base_columns[key]
# Add the Selected Columns dynamically to the Table
for col in user_columns:
self.base_columns[col] = tables.Column(verbose_name=col)
super(AdHocReportTable, self).__init__(data, user_columns, *args, **kwargs)