【问题标题】:Using django-filter with django-tables2, how do I annotate a queryset?使用 django-filter 和 django-tables2,我如何注释查询集?
【发布时间】:2019-02-06 19:57:18
【问题描述】:

我正在使用 django-filter 和 django-tables2 从 SQLite3 数据库中提取数据。该数据库有 15 个以上的销售订单信息字段,每个销售订单可能是多行(行字段)。我想呈现一个相当于“分组依据”销售订单的表格,并对 ExtAmount 字段求和。我知道我应该使用 annotate 函数,但我不确定在哪里使用 django-filter/django-tables2 来实现它。

在 SQL 中,我使用以下内容来获取我需要的内容:

SELECT SalesOrder, Customer, Count(Line) AS Lines, Round(Sum(ExtAmount), 2) AS Amount FROM backlog_backlogData GROUP BY SalesOrder Order By Sum(ExtAmount) DESC limit 100

到目前为止,视图呈现了 tables.py 中的三个字段,但没有对 SalesOrder 进行分组。这很棒,但我似乎无法找到需要注释的地方。我已经阅读了文档并搜索了其他问题,但我似乎无法理解如何使用 django-filter/django-table2。我发现 django-filter 文档中引用的“注释”的唯一地方是 ModelMultipleChoiceFilter 过滤器参考。任何帮助都会很棒!

#models.py

from django.db import models

class backlogData(models.Model):
    Shipto = models.IntegerField()
    Customer = models.CharField(max_length=200)
    City = models.CharField(max_length=200, null=True)
    ST =  models.CharField(max_length=200, null=True)
    GLCo =  models.CharField(max_length=200)
    Parent = models.IntegerField()
    SalesOrder = models.IntegerField()
    CustomerPO =  models.CharField(max_length=200, null=True)
    OrderTyp =  models.CharField(max_length=200)
    Line = models.DecimalField(max_digits=20, decimal_places=1)
    ItemNumber = models.CharField(max_length=200, null=True)
    QtyOrdered = models.IntegerField()
    ExtAmount = models.DecimalField(max_digits=20, decimal_places=2)
    Truck = models.CharField(max_length=200, null=True)
    Stop = models.CharField(max_length=200, null=True)
    ShipClass = models.CharField(max_length=200, null=True)


#tables.py

import django_tables2 as tables
from .models import backlogData

class BacklogTable(tables.Table):

    class Meta:
        model = backlogData
        template_name = 'django_tables2/table.html'
        attrs = {'class': 'table is-fullwidth has-text-centered'}
        fields = ('GLCo','Customer','Truck')


#filters.py

import django_filters
from .models import backlogData 

class BacklogListFilter(django_filters.FilterSet):

    class Meta:
        model = backlogData
        fields = ['GLCo','Truck'] #used to filter after GET


#views.py

from django.views.generic import ListView
from django.db.models.query_utils import Q
from django_tables2 import RequestConfig
from django_filters.views import FilterView

from .utils import PagedFilteredTableView
from .models import backlogData
from .tables import BacklogTable
from .filters import BacklogListFilter

class BacklogListView(FilterView):
    model = backlogData
    template_name = 'backlog/index.html'
    filter_class = BacklogListFilter

    def get_context_data(self, **kwargs):
        context = super(BacklogListView, self).get_context_data(**kwargs)
        filter = BacklogListFilter(self.request.GET, queryset=self.get_queryset())
        table = BacklogTable(filter.qs)
        RequestConfig(self.request).configure(table)
        context['filter'] = table
        context['table'] = table
        return context

【问题讨论】:

  • 不用黑匣子,生活会轻松很多

标签: python django sqlite django-filter django-tables2


【解决方案1】:

您可以将注释添加到传递给BacklogTable 的查询集中:

table = BacklogTable(filter.qs.annotate(...))

有关如何使用.annotate() in django 的文档。您可以使用注释的名称(通过将它们作为关键字参数提供给.annotate())作为 django-tables2 中的列名。

【讨论】:

    猜你喜欢
    • 2021-03-26
    • 2019-04-03
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    • 2011-04-08
    • 2019-12-30
    • 2016-08-17
    • 1970-01-01
    相关资源
    最近更新 更多