0

I have two querysets of model objects that I want to display one after another in an html page.

The first queryset contains a list of local restaurants and the other a list of chain restaurants. So my lists are defined as such:

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

Is there a best practice for listing these restaurants one restaurant after another until the sets are depleted?

For example an html would display the restaurants like this:

localRestaurant1
chain_restaurant1
localRestaurant2
chain_restaurant2
localRestaurant3
chain_restaurant3
...

Edit If one of the sets is depleted then the other set should still continue until it is also depleted. So if one list has 3 objects and the other has 7, it should look like this:

localRestaurant1
chain_restaurant1
localRestaurant2
chain_restaurant2
localRestaurant3
chain_restaurant3
localRestaurant4
localRestaurant5
localRestaurant6
localRestaurant7
Michael Smith
  • 3,307
  • 5
  • 25
  • 43

2 Answers2

0

You could use itertools to combine the querysets, like so:

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

If the two querysets share a common field you can also sort the resulting list (Python 2.4 & later for attrgetter otherwise use a lambda function)

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

Then in your template you just iterate over the list:

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

Should give you the result you're after.

Karl
  • 3,394
  • 2
  • 22
  • 31
  • What is the purpose of chaining the results if there is no field to sort them? The @OozeMeister answer is a good way to do it. – David Dahan Jan 13 '15 at 19:24
0

This function will combine your lists the way you intend:

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

Usage:

restaurants = combine(local_restaurants, chain_restaurants)

Template:

{% for restaurant in restaurants %}
     {{ restaurant.name}}
{% endfor %}
nima
  • 6,566
  • 4
  • 45
  • 57
  • I will give this a try and report back. I tried the solution that was given by @OozeMeister, but it didn't do what I wanted it to do. The "zip solution" stops whenever one of the lists is depleted. I would like the list that still contains objects to continue until it also runs out of objects. – Michael Smith Jan 13 '15 at 20:17
  • I finally had a chance to try this out. This doesn't work. That or I'm iterating through this list wrong. – Michael Smith Jan 13 '15 at 21:35
  • Hmm The zip solution was ok because I could manipulate the objects from each list at the same time-- the problem was that it stopped preemptively. I think with your code the fields have to have the same name. – Michael Smith Jan 13 '15 at 22:59