使用另一个模型的字段在Django中注释

发布于 2025-02-03 22:17:12 字数 2067 浏览 2 评论 0原文

我正在尝试计算一个字段,即当其他两个字段相同时,这是一个总和。问题在于,其中一个字段来自与总和字段相同的模型,而另一个则来自另一个模型。

models.py:

class Node(model.Model):
    text = models.CharField(max_length=100, verbose_name=_('Text'))
    perimeter_ID = models.CharField(max_length=100, verbose_name=_('Perimeter_ID'))
    pos_x = models.FloatField(verbose_name=_('Position X'))
    pos_y = models.FloatField(verbose_name=_('Position Y'))
    class Meta:
        ordering = ['pk']


class Routes(models.Model):
    from_id = models.ForeignKey(Node, on_delete=models.PROTECT, verbose_name=_('From'), related_name='transport_from')
    to_id = models.ForeignKey(Node, on_delete=models.PROTECT, verbose_name=_('To'), related_name='transport_to')
    n_box = models.FloatField(verbose_name=_('Number of boxes'))
    day = models.CharField(max_length=10, verbose_name=_('day'))

    class Meta:
        ordering = ['from_id__id', 'to_id__id']
   

在我的观点中,我是第一次按天进行过滤,因为该请求将是filter/?day = 20220103,然后我想知道> 时的框之和from_idender_id是相同的(code> code> code>对应于to_id的节点的)。因此,我需要以某种方式才能建立to_id节点与其code> code> code> code>之间的关系。

views.py:

class sumByPerimeterListAPIView(ListAPIView):
    queryset = Routes.objects.all()
    filter_backends = [DjangoFilterBackend]
    filter_fields = {
        'day': ["in", "exact"],
    }
    def get(self, request, **kwargs):
        queryset = self.get_queryset()
        filter_queryset = self.filter_queryset(queryset)
        values = filter_queryset.values('from_id')\ # TODO: INCLUDE  perimeter_id OF to_id
            .annotate(n_box=Sum('n_box'))
        return Response(values)

我一直在阅读有关subqueryopertref在DJANGO中的信息/42543978/django-1-11-notating-a-subquery-aggregate”> django 1.11注释子查询骨料。但是这些示例对我来说无效,因为我不需要注释字段code> ender_id。我需要通过from_id(模型路由)和perimeter_id(模型节点)和n_box antotate。

I'm trying to calculate a field that it's a sum agregation when two of other fields are the same. The problem is that one of this fields is from the same model as the sum field, but the other one is from another model.

models.py:

class Node(model.Model):
    text = models.CharField(max_length=100, verbose_name=_('Text'))
    perimeter_ID = models.CharField(max_length=100, verbose_name=_('Perimeter_ID'))
    pos_x = models.FloatField(verbose_name=_('Position X'))
    pos_y = models.FloatField(verbose_name=_('Position Y'))
    class Meta:
        ordering = ['pk']


class Routes(models.Model):
    from_id = models.ForeignKey(Node, on_delete=models.PROTECT, verbose_name=_('From'), related_name='transport_from')
    to_id = models.ForeignKey(Node, on_delete=models.PROTECT, verbose_name=_('To'), related_name='transport_to')
    n_box = models.FloatField(verbose_name=_('Number of boxes'))
    day = models.CharField(max_length=10, verbose_name=_('day'))

    class Meta:
        ordering = ['from_id__id', 'to_id__id']
   

And in my views, I'm first filtering by day as the request will be something like filter/?day=20220103 and then I want to know the sum of boxes when from_id and perimeter_id are the same (the perimeter_id of the node corresponding to to_id). So, I need somehow to make the relation between, the to_id node and its perimeter_id.

views.py:

class sumByPerimeterListAPIView(ListAPIView):
    queryset = Routes.objects.all()
    filter_backends = [DjangoFilterBackend]
    filter_fields = {
        'day': ["in", "exact"],
    }
    def get(self, request, **kwargs):
        queryset = self.get_queryset()
        filter_queryset = self.filter_queryset(queryset)
        values = filter_queryset.values('from_id')\ # TODO: INCLUDE  perimeter_id OF to_id
            .annotate(n_box=Sum('n_box'))
        return Response(values)

I've been reading about subquery and OuterRef in Django, also in the following link: Django 1.11 Annotating a Subquery Aggregate. But these examples are not valid for me as I don't need to annotate the field perimeter_id. I need to agrupate by from_id (model Routes) and perimeter_id (model Node) and annotate by n_box.

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

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

发布评论

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

评论(1

爱的那么颓废 2025-02-10 22:17:12

要获取条件注释,请尝试使用语句在注释中

案例:以下是它的一个示例,

from django.db.models import Count, Case, When, IntegerField
Article.objects.annotate(
    numviews=Count(Case(
        When(readership__what_time__lt=treshold, then=1),
        output_field=IntegerField(),
    ))
)

在您的情况下,您必须更改以下行:

values = filter_queryset.annotate(n_box=Sum(When(Case (from_id=from_id.perimeter_ID, then=n_box), n_box=DecimalField())
            

使用 ,案例然后

我希望它能解决您的条件问题。

另外,看看F表达。在调理方面,它们非常有用。

To get a conditioned annotation, try using the case when statement inside the annotation:

Below is an example of it

from django.db.models import Count, Case, When, IntegerField
Article.objects.annotate(
    numviews=Count(Case(
        When(readership__what_time__lt=treshold, then=1),
        output_field=IntegerField(),
    ))
)

In your case you have to change the below line as follows:

values = filter_queryset.annotate(n_box=Sum(When(Case (from_id=from_id.perimeter_ID, then=n_box), n_box=DecimalField())
            

Try something similar using when, case, and then.

I hope it will solve your conditioning issues.

Also, have a look at F expressions. They are very useful when it comes to conditioning.

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