【问题标题】:Displaying two querysets of model objects one after another in Django?在Django中一个接一个地显示两个模型对象的查询集?
【发布时间】:2015-01-13 19:12:07
【问题描述】:

我有两个模型对象的查询集,我想在 html 页面中一个接一个地显示它们。

第一个查询集包含本地餐馆列表,另一个包含连锁餐馆列表。所以我的列表是这样定义的:

local_restaurants = LocalRestaurants.objects.all()
chain_restaurants = ChainRestaurants.objects.all()

有没有一种最佳做法是一个接一个地列出这些餐厅,直到这些餐厅用完为止?

例如,一个 html 会像这样显示餐厅:

localRestaurant1
chain_restaurant1
localRestaurant2
chain_restaurant2
localRestaurant3
chain_restaurant3
...

编辑 如果其中一组被耗尽,那么另一组应该仍然继续,直到它也被耗尽。所以如果一个列表有 3 个对象,另一个有 7 个对象,它应该如下所示:

localRestaurant1
chain_restaurant1
localRestaurant2
chain_restaurant2
localRestaurant3
chain_restaurant3
localRestaurant4
localRestaurant5
localRestaurant6
localRestaurant7

【问题讨论】:

标签: python django


【解决方案1】:

您可以使用itertools 来组合查询集,如下所示:

from itertools import chain
result_list = list(chain(local_restaurants , chain_restaurants))

如果两个查询集共享一个公共字段,您还可以对结果列表进行排序(Python 2.4 及更高版本用于attrgetter,否则使用lambda 函数)

from operator import attrgetter
result_list = sorted(
    chain(local_restaurants , chain_restaurants),
    key=attrgetter('date_created'))

然后在您的模板中,您只需遍历列表:

{% for item in result_list %}
     {{ item.name}}
{% endfor %}

应该给你你想要的结果。

【讨论】:

  • 如果没有字段对结果进行排序,链接结果的目的是什么? @OozeMeister 的答案是一个很好的方法。
【解决方案2】:

此功能将按照您想要的方式组合您的列表:

def combine(list1, list2):
    if len(list1) < len(list2):
        list3 = list2[len(list1):]
    else:
        list3 = list1[len(list2):]
    return list(sum(list(zip(list1, list2)), ())) + list3

用法:

restaurants = combine(local_restaurants, chain_restaurants)

模板:

{% for restaurant in restaurants %}
     {{ restaurant.name}}
{% endfor %}

【讨论】:

  • 我会试一试并报告。我尝试了@OozeMeister 给出的解决方案,但它并没有达到我想要的效果。每当列表之一用完时,“zip 解决方案”就会停止。我希望仍然包含对象的列表继续,直到它也用完对象。
  • 我终于有机会尝试一下了。这行不通。那或者我正在遍历这个列表是错误的。
  • 嗯 zip 解决方案还可以,因为我可以同时操作每个列表中的对象——问题是它先发制人地停止了。我认为您的代码字段必须具有相同的名称。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-19
  • 2023-02-05
  • 2018-06-06
  • 1970-01-01
  • 2018-03-27
  • 2018-12-04
  • 2021-10-01
相关资源
最近更新 更多