【问题标题】:Count the number of occurrences of certain choices in models计算模型中某些选择的出现次数
【发布时间】:2016-10-15 21:44:34
【问题描述】:

我有以下型号:

class Team(models.Model):
    # stuff
class Event(models.Model):
    # stuff
class Award(models.Model):
    award_type_choices = (
        (1, "some string"), # a lot of these
        (2, "some other str"),
    )
    award_type = models.CharField(choices=award_type_choices)
    specific_choices = (
        (1, "some string"), # etc
        # only a few of these, but all of these can be found inside award_type_choices.
    )

    event = models.ForeignKey(Event)
    recipients = models.ManyToManyField(Team)

我正在尝试计算/注释 Team 赢得符合 specific_choices 序列的奖项的次数。我可以通过这段代码过滤获奖的团队:

reversed_choices = dict((v, k) for k, v in Award.specific_choices)
Team.objects.filter(award__award_type__in=reversed_choices.values())

但是,我不确定应该如何计算这些。我之前使用过CountFExpressionWrapper,但没有广泛了解如何立即执行此操作。

我想我可以通过将与filter 相同的参数放入Count 对象中来接近它,但是当我输入它时我意识到它不起作用,即:

Team.objects.annotate(num_specifics=Count('award__award_type__in=Award.specific_choices'))

对此的任何帮助将不胜感激。

【问题讨论】:

    标签: python django python-3.x django-queryset


    【解决方案1】:
    choices = Award.specific_choices.all()
    
    c = Team.objects.filter(award__award_type__in=choices).count()
    

    【讨论】:

    • 对不起,我觉得我说得不够清楚。我希望annotate 每个团队都有一个字段,即他们有多少次Awardspecific_choices 字段的一部分。此外,specific_choices 只是一个包含int, str 元组的序列。不能打电话给all()
    • 那么就是 Team.objects.annotate(num_specifics=c) 其中 c 是上述返回值。
    • 那不行; AFAIK,您不能在注释中放置查询。此外,它计算的是有多少个团队赢得了这些特定奖项,而不是每个赢得了多少。我正在寻找后者。
    • 如果你想让 Django ORM 遇到你的 specific_choices,通过声明它来使其成为模型字段 specific_choices = models.ForeignKey(Choice) 并在该选项之前的某个地方成为一个模型,至少可以选择类型模型.CharField(max_length....
    【解决方案2】:

    我找到了一些关于 Conditional Aggregation 的 Django 文档,帮助我解决了这个问题。

    def most_specifics():
        reverse_specs = dict((v, k) for k, v in Award.specific_choices)
        return Team.objects.annotate(
            c=Sum(
                Case(
                    When(award__award_type__in=reverse_specs.values(), then=1),
                    default=0,
                    output_field=PositiveSmallIntegerField(),
                )
            )
        ).order_by('-c')
    

    【讨论】:

      【解决方案3】:

      以下代码将在给定模型的特定字段中找到选择的数量:

      my_field=Model._meta.get_field('field_name')
      
      length=len(my_field.choices._display_map)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-01
        • 2018-09-09
        • 2017-11-13
        • 2020-12-07
        • 1970-01-01
        • 2012-11-05
        • 2020-10-15
        相关资源
        最近更新 更多