Zorgan
Zorgan

Reputation: 9123

Ordering a list with 3 model objects

I've got 3 queryset's: Post, Two and AdvertisePost.

The way it currently works is: my site is paginated to have 14 objects on every page. Of those 14 objects it is ordered like this:

1. Post
2. Post
3. Post
4. Post
5. Two
6. Post
7. Post
8. Post
9. Post
10.Two
11.Post
12.Post
13.Post
14.Post

But I would now like to have an AdvertisePost on the 12th slot of every page. Not to replace the Post on the 12th slot, but to push it down. But not to push it down so that it ruins the formation of the next page.

Here's my current code:

two_list = []
returned_list = []

two = Two.objects.all()

for i in two:
    two_list.append(i)

ads = AdvertisePost.objects.all()

posts = Post.objects.all()

for n, post in enumerate(posts):
    returned_list.append(post)
    if len(two_list) > 0 and (n + 1) % 4 == 0 and len(returned_list) % 14 != 0:
        returned_list.append(two_list.pop(0))

paginator = Paginator(returned_list, 14)
page = request.GET.get('page')

try:
    lst = paginator.page(page)
except PageNotAnInteger:
    # If page is not an integer, deliver first page.
    lst = paginator.page(1)
except EmptyPage:
    # If page is out of range (e.g. 9999), deliver last page of results.
    lst = paginator.page(paginator.num_pages)

Any idea how I can fit an AdvertisePost object on every 12th slot of every page?

EDIT

The following code starts off with 5 posts instead of 4. After that the formation works fine (the posts are in batches of 4).

for number in range(all_count):
    if number % 5 == 0 and len(two_list) and number != 0:
        answer.append(two_list.pop())
    elif number % 12 == 0 and len(ads) and number != 0:
        answer.append(ads.pop())
    elif len(posts):
        answer.append(posts.pop())

Upvotes: 2

Views: 70

Answers (1)

Andrei Berenda
Andrei Berenda

Reputation: 1986

two = list(Two.objects.all())

ads = list(AdvertisePost.objects.all())

posts = list(Post.objects.all())

all_count = len(posts) + len(ads) + len(two)
answer = []

for i in range(all_count+1):
    number = i % 14
    if number % 5 == 4 and len(two):
        answer.append(two.pop())
    elif number % 12 == 11 and len(ads):
        answer.append(ads.pop())
    elif len(posts):
        answer.append(posts.pop())
    elif len(two):
        answer.append(two.pop())
    elif len(ads):
        answer.append(ads.pop())

After that, you should paginate answer and return the paginated answer. I think this way is simpler. In the and you can not add

elif len(ads):
    answer.append(ads.pop())

if you may have many ads and few posts or two

Upvotes: 2

Related Questions