Django Queryset获取所有值并首先相关

问题描述

我需要获取带有“客户”字段和关联的第一个电话号码的json响应。

# models.py
class Customer(models.Model):
    
    name = models.CharField(max_length=255)
    surname = models.CharField(max_length=255,)
    ...

class CustomerPhone(models.Model):
    
    customer = models.ForeignKey(Customer,related_name = 'phones',on_delete=models.CASCADE)
    phone_number = PhoneNumberField()
    ...

我的客户可以拥有更多的电话号码,但是在摘要表中,我只希望看到第一部电话(具有最小ID)

当我尝试使用此查询集时:

Customer.objects.all().values('surname','phones__phone_number')

我获得

<QuerySet [{'surname': 'Gates','phones__phone_number': '+39123456789'},{'surname': 'Gates','phones__phone_number': '+3998765431'},{'surname': 'Trump','phones__phone_number': '+32123456001'},'phones__phone_number': '+3298765000'}]>

仅拥有一个电话号码的客户我只能获得一个结果吗? 我能得到什么

解决方法

您可以使用SubQuery expresssion [Django-doc]

from django.db.models import OuterRef,Subquery

Customer.objects.values('surname').annotate(
    phone_number=Subquery(
        CustomerPhone.objects.filter(
            customer_id=OuterRef('pk')
        ).order_by('pk').values('phone_number')[:1]
    )
)
,

您在CustomerPhoneCustomer之间的关系是ForeignKey,因此Customer将具有customer_phone_set字段。您需要做的是:

 customer = Customer.objects.get(surname="example")
 first_phone_number = customer.customer_phone_set.first()