【发布时间】:2020-06-29 15:41:45
【问题描述】:
我有这个Django 应用程序,我在其中使用 Highchart 显示一些数据(这里只是一个示例)。
我有两个单独的视图,一个是在 Product 表上执行过滤器(除其他外),另一个视图从 History 表构建 Json 以“传递”到绘图的 AJAX 函数(真实数据相当沉重)。
数据基于我有 product_id, year, quantity 的 History 表(我想显示随时间变化的数量)。
在我的模型中,我还有一个Products 和products, category 的表格(每个产品都有一个类别,多个产品可以共享同一个类别)。
这两个表与字段product是一对多的关系。
在我的模板中,我希望用户能够通过 category 字段过滤products(即:过滤类别为“A”的产品),并且此过滤器应该还更新图表(即:我想查看“A”类产品的历史记录)。
在我的代码下面,我尝试了很多尝试,但到目前为止都没有成功。
如果代码包含您需要的所有信息,请告诉我,我已尝试仅获取基本信息。
models.py
class Products(models.Model):
product = models.TextField(primary_key=True)
category = models.TextField(blank=True,null=True)
# ...
class HistoryProducts(models.Model):
product_id = models.ForeignKey(Products)
year = models.TextField(blank=True, null=True)
quantity = models.DecimalFeld(..)
# ...
filters.py
import django_filters
class ProductsFilter(django_filters.FilterSet):
category_contains = CharFilter(field_name='category', lookup_expr='icontains')
class Meta:
model = Products
fields = ['category']
views.py
def index(request):
products = Products.objects.all()
myFilter = ProductsFilter(request.GET, queryset=products)
products = myFilter.qs
# ...
return render(request, 'index.html', context={..})
def chart_data(request):
# maybe here we should filter History by myFilter, but can't find how
# ...
# calculate total quantity
history = HistoryProducts.objects.values('year').order_by('year').annotate(Total=Sum('quantity'))
chart = {
'chart': {'type': 'column'},
'title': {'text': 'Quantity by Year'},
'series': [{
'name': 'Quantity',
'data': list(map(lambda row: {'name': round(row['year']),'y': round(row['Total'])}, history))
}]
}
return JsonResponse(chart)
index.html
<!-- Filter -->
<form method="GET">
{{myFilter.form}}
<button type="submit"> Filter</button>
</form>
<!-- Chart -->
<div>
<div id="container" data-url="{% url 'chart_data' %}"></div>
</div>
<!-- Scripts -->
<script src="https://code.highcharts.com/highcharts.src.js"></script>
<script>
// highchart function
$.ajax({
url: $("#container").attr("data-url"),
dataType: 'json',
success: function (data) {
Highcharts.chart("container", data);
}
});
</script>
我想我的问题是:是否可以将使用django-filters 构建的同一个表单过滤器“连接”到多个模型?
或者更一般地说,有人会如何解决这类问题?我愿意接受任何建议。谢谢
编辑---
我找到了一个不漂亮的解决方案,而且还让页面变慢了。
views.py
def index(request):
products = Products.objects.all()
myFilter = ProductsFilter(request.GET, queryset=products)
products = myFilter.qs
# get the id filtered
ids = []
qs = products.values_list('products',flat=True)
for i in qs:
ids.append(i)
# use ids to filter History
history = History.objects.filter(product_id_in=ids).values('year').order_by('year').annotate(Total=Sum('quantity'))
# make the json here
chart = {
'chart': {'type': 'column'},
'title': {'text': 'Quantity by Year'},
'series': [{
'name': 'Quantity',
'data': list(map(lambda row: {'name': round(row['year']),'y': round(row['Total'])}, history))
}]
}
dump = json.dumps(chart)
# return the json to the template
return render(request, 'index.html', context={..})
现在我只需要模板中的这一部分:
<script>
Highcharts.chart('container', {{ chart|safe }});
</script>
基本上,我将 Json 移到了过滤数据的同一视图中,但这要慢得多。
【问题讨论】:
-
我开始了赏金,因为我没有找到任何与此相关的东西,这似乎是一个典型的场景(其他人可能会觉得这很有帮助)。如果问题不清楚或缺少一些关键信息,请告诉我,以便我改进。
标签: javascript python jquery django