【问题标题】:list not working in a query列表在查询中不起作用
【发布时间】:2011-02-28 15:34:25
【问题描述】:

谁能告诉我为什么这个查询只有在我硬编码phone_type时才会处理

#model.py

class ClientPhone(models.Model):
    client = models.ForeignKey(Client, editable=False)
    ...
    phone_type = models.CharField(max_length=5, choices=PHONE_CHOICES)
    number = models.CharField(max_length=24)

# models.py

PHONE_CHOICES = (
    ('home', 'Home'),
    ('home2', 'Home 2'),
    ('mobi', 'Mobile'),
    ('mobi2', 'Mobile 2'),
    ('work', 'Work'),
    ('work2', 'Work 2'),
)

# views.py

    phones = [ClientPhone.objects.filter(client=i_clientKEY).filter(phone_type=k).latest('created') for k, v in PHONE_CHOICES]

# shell

>>> from client.models import ClientPhone
>>> phones = [ClientPhone.objects.filter(client=1).filter(phone_type=k).latest('created') for k, v in PHONE_CHOICES]
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 395, in latest
    return obj.get()
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 341, in get
        % self.model._meta.object_name)
DoesNotExist: ClientPhone matching query does not exist.
>>> phones = [ClientPhone.objects.filter(client=1).filter(phone_type='home').latest('created') for k, v in PHONE_CHOICES]
>>> phones
[<ClientPhone: ClientPhone object>, <ClientPhone: ClientPhone object>, <ClientPhone: ClientPhone object>, <ClientPhone: ClientPhone object>, <ClientPhone: ClientPhone object>, <ClientPhone: ClientPhone object>]

【问题讨论】:

    标签: python django django-views django-queryset


    【解决方案1】:

    latest() 如果没有找到匹配项,则会引发异常,因此除非每个客户端都有每个 phone_type,否则当客户端没有 homehome2、@ 之一时,您将收到异常987654325@等选择。

    在第二个示例中,您只需要查找home,它显然具有latest() 的有效结果。

    一种方法:

    latest_phones = []
    for k, v in PHONE_CHOICES:
        try:
            latest_phones.append(ClientPhone.objects.filter(client=i_clientKEY, phone_type=k).latest('id'))
        except ClientPhone.DoesNotExist:
            pass 
    

    如果您只对模型中的某些特定值感兴趣,另一种更有效的方法:

    client_phone_numbers = ClientPhone.objects.filter(client=i_clientKEY)\
         .order_by('-created').values_list('phone_type', 'phone_number').distinct()
    
    # returns list of all `phone_type` and its latest `phone_number` for this client
    # if you don't need all phone types, specifically filter them in the first filter
    # eg: filter(phone_type__in=['home','mobi'])
    

    【讨论】:

    • 那么我应该通过try 传递查询吗?
    • 这将使您的第一个异常查找失败!我只是遍历PHONE_CHOICES 并包装每次获取尝试。发布替代方案...
    【解决方案2】:

    您可以使用get_or_create() 方法代替latest() 以确保所有电话类型都在数据库中。

    【讨论】:

    • 如果它不存在就不需要创建它。对不起:(
    猜你喜欢
    • 1970-01-01
    • 2021-01-18
    • 2012-04-08
    • 2016-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多