Используя django-фильтр с django-tables2, как мне аннотировать набор запросов? - PullRequest
0 голосов
/ 31 августа 2018

Я использую django-filter и django-tables2 для извлечения данных из базы данных SQLite3. База данных содержит более 15 полей информации о заказе на продажу, где они могут состоять из нескольких строк (поле Строка) на один заказ на продажу. Я хотел бы визуализировать таблицу, которая соответствует эквиваленту заказа на продажу «Group By», и суммировать поле ExtAmount. Я знаю, что должен использовать функцию аннотирования, но я не уверен, где это реализовать с помощью 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-фильтра, - это ссылка на фильтр 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

1 Ответ

0 голосов
/ 02 сентября 2018

Вы можете добавить свои аннотации к набору запросов, переданному в BacklogTable:

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

Документация по использованию .annotate() в Django . Вы можете использовать имя аннотации (предоставляя их в качестве аргументов ключевых слов для .annotate()) в качестве имен столбцов в django-tables2.

...