在聚合中使用模型方法

发布于 2024-12-04 03:50:01 字数 1607 浏览 5 评论 0原文

我正在尝试在 django 聚合查询中使用模型方法。我不确定这是否可能,而且我可能会以错误的方式进行。

这是我要查询的型号。

class ClassNumbers(models.Model):
   """
   The class year level and number inline model for a booking
   """
   booking = models.ForeignKey('Booking')
   yearLevel = models.CharField(max_length=10, choices=YEAR_CHOICES, verbose_name='Year Level')
   numberOfStudents = models.IntegerField(verbose_name='Number of Students') 

class Booking(models.Model):
   # A shorter version of the model
   date = models.DateField()
   institution = models.ForeignKey(Institution)

   def getStudentTotal(self):
      # Total class numbers
      classes = ClassNumbers.objects.filter(booking=self.id)
      classTotal = 0
      if ( classes ):
          for c in classes:
              classTotal += c.numberOfStudents
      return classTotal

   def getHDSV(self):
      HDSVunits = {
                'Full-Day': 2.0,
                'Half-Day AM': 1.0,
                'Half-Day PM': 1.0,
                'Three-Quarter Day': 1.5,
                '1 Hour': 0.5,
                'Custom': 1.0,
                }
      numStudents = self.getStudentTotal()
      result = numStudents * HDSVunits[self.price.name]
      return result

getHDSV 方法返回应用所在内部使用的报告指标。我希望将指标聚合为日期期间内一个月的总计。

我不是聚合/注释大师。到目前为止我的尝试还没有达到我想要的结果。

最终,我查询了指定日期之间的 Bookings,然后循环遍历结果,并通过每次迭代调用 getHDSV 方法将报告单元记录到字典中。当然,生成的字典没有按照我想要的方式排序。 所以我现在寻求一些帮助。

考虑到指标的生成方式,我可以在查询中聚合数据时调用模型方法吗?或者我应该在创建聚合时使用HDSVunits字典?或者有更好的方法吗?

谢谢。

I am trying to use a model method in a django aggregate query. I'm not sure if it is possible and I may be going at this the wrong way.

Here is the model I wish to query.

class ClassNumbers(models.Model):
   """
   The class year level and number inline model for a booking
   """
   booking = models.ForeignKey('Booking')
   yearLevel = models.CharField(max_length=10, choices=YEAR_CHOICES, verbose_name='Year Level')
   numberOfStudents = models.IntegerField(verbose_name='Number of Students') 

class Booking(models.Model):
   # A shorter version of the model
   date = models.DateField()
   institution = models.ForeignKey(Institution)

   def getStudentTotal(self):
      # Total class numbers
      classes = ClassNumbers.objects.filter(booking=self.id)
      classTotal = 0
      if ( classes ):
          for c in classes:
              classTotal += c.numberOfStudents
      return classTotal

   def getHDSV(self):
      HDSVunits = {
                'Full-Day': 2.0,
                'Half-Day AM': 1.0,
                'Half-Day PM': 1.0,
                'Three-Quarter Day': 1.5,
                '1 Hour': 0.5,
                'Custom': 1.0,
                }
      numStudents = self.getStudentTotal()
      result = numStudents * HDSVunits[self.price.name]
      return result

The getHDSV method returns a reporting metric used internally where the app lives. I wish to aggregate the metric into a total for the month between a date period.

I am no aggregate/annotate master. My attempts so far have not netted the results I'm after.

Ultimately I queried Bookings between the specified dates and then looped over the results and tallied the reporting unit into a dictionary by calling the getHDSV method each iteration. Of course the resulting dictionary is not sorted the way I would like.
So I am now turning to get some help.

Given the way the metric is generated can I call a model method while aggregating data in a query? Or should I be using the HDSVunits dictionary while creating the aggregate? Or is there a better way?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

墨离汐 2024-12-11 03:50:01

您的设置相当困难,在 Price 模型上映射 HDSVunits 可能会更容易,以便更容易在查询中访问。

我能想到的最好的办法是这样的:

Booking.objects.aggregate(
    hdsv=(
        Sum('classnumbers__numberofstudents') * 
        Case(
            When(price__name='Full-Day', then=2.0),
            When(price__name='Half-Day AM', then=1.0),
            When(price__name='Full-Day PM', then=1.0),
            When(price__name='Three-Quarter Day', then=1.5),
            When(price__name='1 Hour', then=0.5),
            When(price__name='Custom', then=1.0),
            output_field=FloatField(),
        )
    )
)

如果 HDSV 值存储为 Price 模型上的字段,您可以简单地执行以下操作:

Booking.objects.aggregate(
    hdsv=Sum('classnumbers__numberofstudents') * F('price__hdsv'))

顺便说一句,您确实应该考虑遵循 < a href="https://www.python.org/dev/peps/pep-0008/#naming-conventions" rel="nofollow">Python 命名约定 这将使其他 Python 开发人员更容易帮助你。

You've got quite a difficult setup, it might be easier to have the HDSVunits mapping on the Price model to make it easier to access in queries.

The best I can come up with is something like this:

Booking.objects.aggregate(
    hdsv=(
        Sum('classnumbers__numberofstudents') * 
        Case(
            When(price__name='Full-Day', then=2.0),
            When(price__name='Half-Day AM', then=1.0),
            When(price__name='Full-Day PM', then=1.0),
            When(price__name='Three-Quarter Day', then=1.5),
            When(price__name='1 Hour', then=0.5),
            When(price__name='Custom', then=1.0),
            output_field=FloatField(),
        )
    )
)

If the HDSV value were stored as a field on the Price model, you could simply do:

Booking.objects.aggregate(
    hdsv=Sum('classnumbers__numberofstudents') * F('price__hdsv'))

On a side note, you should really consider following the Python naming convensions which would make it easier for other Python developers to help you.

弃爱 2024-12-11 03:50:01

如果 getHDSV 返回的数据不是来自数据库,则 aggregateannotate 将无法用于收集其统计信息。

If the data that getHDSV is returning is not from the database then aggregate and annotate will not be able to be used to gather statistics on it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文