Javascript 如何基于多对一关系过滤Highchart绘图数据?

Javascript 如何基于多对一关系过滤Highchart绘图数据?,javascript,python,jquery,django,Javascript,Python,Jquery,Django,我有一个Django应用程序,其中我使用Highchart显示了一些数据(这里只是一个示例) 我有两个独立的视图,一个视图在产品表上执行过滤(除其他外),另一个视图从历史表构建Json,以“传递”到绘图的AJAX函数(实际数据相当重) 数据基于历史表格,其中我有产品id、年份、数量(我想显示一段时间内的数量) 在我的模型中,我还有一个表,用于产品和产品,类别(每个产品都有一个类别,多个产品可以共享同一类别) 这两个表与字段product具有一对多关系 在我的模板中,我希望用户能够通过类别字段过滤

我有一个
Django
应用程序,其中我使用Highchart显示了一些数据(这里只是一个示例)

我有两个独立的视图,一个视图在
产品
表上执行过滤(除其他外),另一个视图从
历史
表构建Json,以“传递”到绘图的AJAX函数(实际数据相当重)

数据基于
历史
表格,其中我有
产品id、年份、数量
(我想显示一段时间内的数量)

在我的模型中,我还有一个表,用于
产品
产品,类别
(每个产品都有一个类别,多个产品可以共享同一类别)

这两个表与字段
product
具有一对多关系

在我的模板中,我希望用户能够通过
类别
字段过滤
产品
(即:过滤类别为“A”的产品),此过滤器还应更新图表(即:我只想查看类别为“A”的产品的历史记录)

在我的代码下面,我尝试了很多次,但到目前为止都没有成功

请让我知道,如果代码有你需要的所有信息,我已经尝试采取的只是基本的

models.py 过滤器.py views.py index.html 现在我只需要模板中的此部分:

<script>
  Highcharts.chart('container', {{ chart|safe }});
</script>

图表('container',{{chart | safe}});

基本上,我将Json移动到同一个视图中,在该视图中过滤数据,但是这要慢得多。

这更像是一个jQuery/Javascript问题,但是如果您将
id
属性分配给表单的HTML元素,然后使用
$.getJSON
图表数据
视图中获取数据,则应该可以捕获表单提交

e、 g

//假设您为表单分配了id=“filter form”
$(“#筛选表单”).submit(函数(事件){
event.preventDefault();
var url=$(“#容器”).attr(“数据url”);
var formData=$(“#过滤器形式”).serialize()
$.getJSON(url、formData、函数(数据){
图表(“容器”,数据);
})
});
然后,您将能够使用
请求中的
产品过滤器
。在
图表中获取
数据,就像在
索引中那样

def图表数据(请求):
products=products.objects.all()
myFilter=ProductsFilter(request.GET,queryset=products)
products=myFilter.qs
HistoryProducts.objects.filter(
product_id__in=产品
).值('year')。按('year')排序。注释(
总计=总和(“数量”)
)
图表={
'图表':{'type':'column'},
'title':{'text':'Quantity by Year'},
“系列”:[{
“名称”:“数量”,
“数据”:列表(映射(lambda行:{'name':四舍五入(行['year']),'y':四舍五入(行['Total']),历史))
}]
}
返回JsonResponse(图表)

我开始悬赏,因为我没有发现任何与此相关的东西,这似乎是一个典型的场景(其他人可能会觉得这很有帮助)。如果问题不清楚或缺少一些关键信息,请告诉我,以便我可以改进它。谢谢你的回答,现在它几乎可以工作了。但是当第一次加载页面时,只有在我从表单发出请求之后,才会显示绘图。是否可以修复此问题,以便即使未进行筛选,也能显示绘图?同样在
index()
中,我有一个在您提出筛选请求后可用的
产品的计数,但现在它不起作用。似乎
ProductsFilter
内部
index
已损坏,您知道问题所在吗?老实说,我没有标记这个jQuery/JS,因为一开始我想看看是否有“Django”解决方案。我的主要问题是使用表中的筛选器来筛选其他相关表,但不是在同一视图中。(抱歉三重评论)>是否可以修复此问题,以便即使未进行筛选,也能显示绘图?当然,如果您保留初始的
或添加一个
$(function(){})
请求通过序列化表单检索JSON,那么它仍然应该加载。我不明白为什么我们要筛选产品而不是HistoryProducts。除了命名约定和缺少索引之外,您只需
HistoryProducts.objects.filter(product\u id\uu\u category\uu icontains=value)
import django_filters
class ProductsFilter(django_filters.FilterSet):
    category_contains = CharFilter(field_name='category', lookup_expr='icontains') 
    class Meta:
         model = Products
         fields = ['category']
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)
<!-- 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>
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>