【问题标题】:Django-Filter over ManagersDjango-过滤管理器
【发布时间】:2020-09-15 12:00:14
【问题描述】:

我已经被困在这几个星期了,我相信答案非常简单,但不知何故我无法在网上的任何地方找到它。这让我觉得我完全错了。

我想要做的就是能够过滤我的统计数据,例如基于django-filter 包的get_largest_winning_trade 函数。我哪里错了?作为旁注,get_largest_winning_trade 显示了交易模型中最大的获胜交易,但没有按照我的标准进行过滤。比如“用户”。

managers.py

from django.db import models

class TradeQuerySet(models.QuerySet):

    def get_users_trades(self, username):
        return self.filter(user__username=username)

class TradeManager(models.Manager):

    def get_queryset(self):
        return TradeQuerySet(self.model, using=self._db)

    def get_users_trades(self, username):
        return self.get_queryset().get_users_trades(username)

    def get_largest_winning_trade(self):
        return max([t.profit_loss_value_fees for t in self.all()])

views.py

class StatsView1(LoginRequiredMixin, ListView):
    model = Trade
    template_name = 'dashboard/stats1.html'

    def get_context_data(self, **kwargs):
        filter = StatsFilter1(self.request.GET, queryset=self.get_queryset())
        context = super().get_context_data(**kwargs)
        context['filter'] = filter
        context['get_largest_winning_trade'] = Trade.objects.get_largest_winning_trade
        return context

stats.html(测试)

        filter.qs.get_largest_winning_trade: {{ filter.qs.get_largest_winning_trade }} <br>
        Trade.get_largest_winning_trade: {{ Trade.get_largest_winning_trade }} <br>
        trade.get_largest_winning_trade: {{ trade.get_largest_winning_trade }} <br>
        get_largest_winning_trade: {{ get_largest_winning_trade }} <br>  # works but not with filter

要求的其他信息

分享了这门课,它很长,所以我试着把它减少到最有帮助的地方。如果还有其他问题,请告诉我。

models.py

class Trade(models.Model):
    class Meta:
        verbose_name = "Trade"
        verbose_name_plural = "Trades"
     ...

     user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)
     status = models.CharField(max_length=2, choices=STATUS_CHOICES, default='cl')
     type = models.CharField(max_length=5, choices=TYPE_CHOICES, default=LONG)
     broker = models.ForeignKey(Broker, on_delete=models.CASCADE, blank=True, null=True)
     asset = models.ForeignKey(Asset, default=DEFAULT_ASSET_ID, on_delete=models.CASCADE, null=True)
     #AUTOMATED FIELDS
     profit_loss_value_fees = models.FloatField(null=True)
     objects = TradeManager()
     ...

     def save(self):
         ...
         self.profit_loss_value_fees = self.get_profit_loss_value_fees()
         return super(Trade, self).save()

     ...

【问题讨论】:

  • 有人投了反对票,但从未发表评论,为什么......不是很有帮助

标签: django django-models django-queryset django-filter django-managers


【解决方案1】:

也许你可以使用qs 属性来做这样的事情:

def get_context_data(self, **kwargs):
    filter = StatsFilter1(self.request.GET, queryset=self.get_queryset())
    context = super().get_context_data(**kwargs)
    context['filter'] = filter
    context['get_largest_winning_trade'] = filter.qs.get_largest_winning_trade
    return context

更新

我认为与其做经理,不如在这里使用aggregation 进行计算。像这样:

from django.db.models import Max
...

context['get_largest_winning_trade'] = filter.qs.aggregate(max_value=Max('profit_loss_value_fees'))['max_value']

使用聚合的原因是为了减少 DB 命中,因为你的 manager 方法会在循环迭代期间多次命中数据库。

【讨论】:

  • 感谢@ruddra 的潜在答案!这只会让我收到“TradeQuerySet”对象没有属性“get_largest_winning_trade”的错误消息
  • 可以分享模型吗?
  • 哇,我想你解决了!这么长时间以来,这一直是我的眼中钉,明天将进行更多的统计数据计算,如果我发现任何其他可能有益于这个答案的东西,请在此处发布。再次感谢!
猜你喜欢
  • 2013-07-26
  • 2011-11-09
  • 2011-02-24
  • 2021-01-01
  • 2011-11-13
  • 2011-03-05
  • 2011-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多