Django Annotate - 连接上次创建的 ManyToMany 对象字段

问题描述 投票:0回答:2
class User(models.Model):
    name=CharField()


class Address(models.Model):
    user= Foreignkey(user, related_name="Addresses")
    buildingname=CharField()
    street=CharField()
    ...

我有一个像 top 这样的模型,想要提取如下所列的数据。

{
    [
        ['USERNAME1', 'A XYZBUILDING 14 Drain St. '],
        ['USERNAME2', 'C XXXBUILDING 13 Drain St. '],
        ['USERNAME3', 'B ZZZBUILDING 12 Drain St. '],
        ...
    ]
    
}

另外作为一种解决方法,这是最接近答案的事情,但我无法完成

无需循环每个用户

无需在额外方法的选择字段中执行原始sql

我想用 Django ORM 来实现这个目标。

mysql django orm prefetch annotate
2个回答
1
投票

实际上你在子查询中做错了,你必须这样编写子查询:-

from django.db.models import OuterRef

address_subquery = Address.objects.filter(user=OuterRef('pk')).order_by('created')

您可以从这里参考https://docs.djangoproject.com/en/3.2/ref/models/expressions/#subquery-expressions


0
投票

可能不是最好的解决方案,但它满足了要求。

from django.db.models import Subquery, CharField, Value, F, OuterRef
from django.db.models.functions import Coalesce, Trim, Concat

from myfile import my_custom_filters, Address, User

address_subquery = Address.objects.filter(
    user__id=OuterRef('id')
).order_by('-created')
User.objects.filter(**my_custom_filters).annotate(
    street_str=Subquery(
        Coalesce(
            address_subquery.values_list('street', flat=True)[:1], 
            Value("")
        ),
        output_field=CharField()
    ),
    building_name_str=Subquery(
        Coalesce(
            address_subquery.values_list('building_name', flat=True)[:1], 
            Value("")
        ),
        output_field=CharField()
    )
).annotate(
    address_text_str=Trim(
        Concat(
            F('street_str'),
            Value(" "),
            F('building_name_str')
        )
    )
).values_list('name', 'address_text_str')
© www.soinside.com 2019 - 2024. All rights reserved.