列表在查询中不起作用

发布于 2024-10-19 14:27:48 字数 1601 浏览 2 评论 0原文

谁能告诉我为什么这个查询只有在我硬编码 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>]

Can anyone tell me why this query will only process if I hard code 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>]

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

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

发布评论

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

评论(2

友谊不毕业 2024-10-26 14:27:48

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

在第二个示例中,您只需要查找 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'])

latest() raises an exception if no matches are found, so unless each client has every single phone_type, you will get an exception when a client doesn't have one of the home, home2, mobi, etc choices.

In the second example, you are only ever looking for home, which apparently has a valid result for latest().

One method:

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 

Another more efficient method if you're interested in only some specific values from the model:

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'])
温柔少女心 2024-10-26 14:27:48

您可以使用 get_or_create() 方法而不是 latest() 来确保所有手机类型都在数据库中。

You can use get_or_create() method instead of latest() to ensure that all phone types are in the database.

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