Django-Filter 包:如何过滤对象以创建统计信息而不是列表
Django-Filter Package: How To Filter Objects To Create Stats And Not Lists
我正在使用 Django-Filter 包,该包在他们文档中的一个示例中运行良好。但是,我并不是要生成对象列表,而是要过滤我在对象字段上所做的计算。
示例模板:https://django-filter.readthedocs.io/en/stable/guide/usage.html#the-template
{% for obj in filter.qs %}
{{ obj.name }} - ${{ obj.price }}<br />
{% endfor %}
这里的问题是创建了一个列表。我正在寻找我的交易 "stats" 以根据新的过滤器选择进行更新。
我认为我需要以不同的方式设置我的视图,并且可能还以其他方式调用模板对象,但不完全确定。
filters.py
class StatsFilter(django_filters.FilterSet):
class Meta:
model = Trade
fields = ['type', 'asset', 'symbol', 'broker', 'patterns', 'associated_portfolios']
views.py
class StatsView(LoginRequiredMixin, FilterView):
model = Trade
template_name = 'dashboard/stats.html'
filterset_class = StatsFilter
def get_form(self, *args, **kwargs):
form = StatsFilter()
user = self.request.user
form.fields['associated_portfolios'].queryset = Portfolio.objects.filter(user=user)
return form
def get_context_data(self, *args, **kwargs):
trade = Trade.objects.filter(user=self.request.user, status='cl').order_by('created')
all_trades = Trade.objects.filter(user=self.request.user, status='cl').count()
context = super(StatsView, self).get_context_data(*args, **kwargs)
data = [t.profit_loss_value_fees for t in trade]
context['all_trades'] = all_trades
context['gross_profit'] = sum([t.profit_loss_value for t in trade])
context['net_profit'] = sum([t.profit_loss_value_fees for t in trade])
...
return context
stats.html
<form method="get" class="row">
{{ filter.form.as_p }}
{{ form.media }}
<div class="col-xl-12">
<button class="btn btn-success float-right" type="submit">Apply</button>
</div>
</form>
<table class="table table-striped">
<tr>
<th scope="row">Net Profit <small>(Fees Included)</small></th>
<td>
{% if net_profit >= 0 %}
<font color="green">{{ net_profit|floatformat:2 }}</font>
{% else %}
<font color="red">{{ net_profit|floatformat:2 }}</font>
{% endif %}
</td>
</tr>
<tr>
<th scope="row">Gross Profit</th>
<td>{{ gross_profit|floatformat:2 }}</td>
</tr>
我花了数周时间才发现的秘诀是如此明显。 运行 过滤器计算。下面的例子。您也不需要使用聚合。与我上面写的原始方式一样有效。
context['gross_profit'] = sum([t.profit_loss_value for t in trade])
这是关键部分:
trades = filter.qs.filter(status='cl')
view.py
def get_context_data(self, *args, **kwargs):
filter = StatsFilter(self.request.GET, queryset=self.get_queryset(), request=self.request)
trades_count = filter.qs.filter(status='cl').count()
trades = filter.qs.filter(status='cl')
...
context['gross_profit'] = trades.aggregate(value=Sum('profit_loss_value'))['value']
我正在使用 Django-Filter 包,该包在他们文档中的一个示例中运行良好。但是,我并不是要生成对象列表,而是要过滤我在对象字段上所做的计算。
示例模板:https://django-filter.readthedocs.io/en/stable/guide/usage.html#the-template
{% for obj in filter.qs %}
{{ obj.name }} - ${{ obj.price }}<br />
{% endfor %}
这里的问题是创建了一个列表。我正在寻找我的交易 "stats" 以根据新的过滤器选择进行更新。
我认为我需要以不同的方式设置我的视图,并且可能还以其他方式调用模板对象,但不完全确定。
filters.py
class StatsFilter(django_filters.FilterSet):
class Meta:
model = Trade
fields = ['type', 'asset', 'symbol', 'broker', 'patterns', 'associated_portfolios']
views.py
class StatsView(LoginRequiredMixin, FilterView):
model = Trade
template_name = 'dashboard/stats.html'
filterset_class = StatsFilter
def get_form(self, *args, **kwargs):
form = StatsFilter()
user = self.request.user
form.fields['associated_portfolios'].queryset = Portfolio.objects.filter(user=user)
return form
def get_context_data(self, *args, **kwargs):
trade = Trade.objects.filter(user=self.request.user, status='cl').order_by('created')
all_trades = Trade.objects.filter(user=self.request.user, status='cl').count()
context = super(StatsView, self).get_context_data(*args, **kwargs)
data = [t.profit_loss_value_fees for t in trade]
context['all_trades'] = all_trades
context['gross_profit'] = sum([t.profit_loss_value for t in trade])
context['net_profit'] = sum([t.profit_loss_value_fees for t in trade])
...
return context
stats.html
<form method="get" class="row">
{{ filter.form.as_p }}
{{ form.media }}
<div class="col-xl-12">
<button class="btn btn-success float-right" type="submit">Apply</button>
</div>
</form>
<table class="table table-striped">
<tr>
<th scope="row">Net Profit <small>(Fees Included)</small></th>
<td>
{% if net_profit >= 0 %}
<font color="green">{{ net_profit|floatformat:2 }}</font>
{% else %}
<font color="red">{{ net_profit|floatformat:2 }}</font>
{% endif %}
</td>
</tr>
<tr>
<th scope="row">Gross Profit</th>
<td>{{ gross_profit|floatformat:2 }}</td>
</tr>
我花了数周时间才发现的秘诀是如此明显。 运行 过滤器计算。下面的例子。您也不需要使用聚合。与我上面写的原始方式一样有效。
context['gross_profit'] = sum([t.profit_loss_value for t in trade])
这是关键部分:
trades = filter.qs.filter(status='cl')
view.py
def get_context_data(self, *args, **kwargs):
filter = StatsFilter(self.request.GET, queryset=self.get_queryset(), request=self.request)
trades_count = filter.qs.filter(status='cl').count()
trades = filter.qs.filter(status='cl')
...
context['gross_profit'] = trades.aggregate(value=Sum('profit_loss_value'))['value']