0

I'm trying to implement pagination. I'm mainly following django documentation for pagination,https://docs.djangoproject.com/en/1.8/topics/pagination/...I'm not sure what i did wrong but the pagination effect is not being activated: When I set page to only have three posts, it still shows nine posts. I didn't do anything special, I just followed the documentation.

def category_detail(request, slug):

    obj = NewsCategory.objects.get(slug=slug)
    newsInCat = obj.news_set.all() #for the list of news
    paginator = Paginator(newsInCat, 3) # Show 25 contacts per page
    page = request.GET.get('page')
    try:
        news_set = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        news_set = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        news_set = paginator.page(paginator.num_pages)


bestInCat = obj.news_set.get_bestInCat()
specialInCat = obj.news_set.get_special()
mustSeeInCat = obj.news_set.get_mustSeeInCat()
recommend = obj.news_set.get_recommend()
ad2 = Sponsored.objects.get_ad2()

context = {
    "obj":obj, 
    "news_set":news_set,
    "newsInCat":newsInCat,
    "bestInCat":bestInCat,
    "specialInCat":specialInCat,
    "mustSeeInCat":mustSeeInCat,
    "recommend":recommend,
    "ad2":ad2
}

and the below is my html...beside pagination, I'm having one more issue. When the title of the post becomes too long that it breaks another line, the format of my page gets messed up. It looks like this

enter image description here

enter image description here

<div class="row">
<article>
  {% for news in newsInCat %}
  <div class='col-sm-4'>

    <div class="content">
    <figure class="story-image">
      <a href='{{news.get_absolute_url }}'><img src="{{news.get_image_url}}"  class="img-rounded" alt="Cinque Terre" width="360" height="267"></a>
    </figure>
      <div id="forever "style="margin-bottom:30px;">
      <a href='{{news.get_absolute_url }}' style="text-decoration:none; color:#282E5C;"><h4 style="font-size: 18px;
    font-weight: 400;">{{news.title}}</h4></a>
  </div>
        </div>
  </div>
  {% endfor %}
</article>
</div>


<div class="pagination">
    <span class="step-links">
        <!-- {% if news_set.has_previous %}
            <a href="?page={{ news_set.previous_page_number }}">previous</a>
        {% endif %}

        <span class="current">
            Page {{ news_set.number }} of {{ news_set.paginator.num_pages }}.
        </span> -->

        {% if news_set.has_next %}
            <a href="?page={{ news_set.next_page_number }}">Load More</a>
        {% endif %}
    </span>
</div>
winixxee
  • 564
  • 1
  • 10
  • 30

3 Answers3

1

There are two separate problems at work here which have been indicated in the above answers:

  1. You are not using Bootstrap correctly: although you can append multiple <div class="col-sm-4"> together, you will see the irregular collapsing behavior in your screenshot if they are different heights. The purpose of <div class="row"> is to ensure that your columns will appear in separate rows. See Must Bootstrap container elements include row elements? for more information.

    You can resolve this with code like the following in your for-loop to add a new row every third item:

    {% if forloop.counter|divisibleby:3 %}
    </div>
    <div class="row">
    {% endif %}
    
  2. You are not using the correct context object in your template: The paginator object is passed as news_set in your context object but the template uses another context object: newsInCat, which is not paginated. If you follow @Sayse's suggestion of using the news_set object, you should be in good shape:

    {% for news in news_set %}
    

As a final suggestion, the <article> tag does not seem to be doing anything besides giving semantic value. Why not just use it instead of the div, so that you have <article class="col-sm-4">?

And as a final note, camelCase is generally frowned on in Python. Try using_underscores_with_lowercase, like you've already done with news_set.

Adding all these suggestions, you would only need to amend your template to something like this:

<div class="row">
  {% for news in news_set %}
  <article class="col-sm-4">
    <!-- add your article content here...and clean it up! You have unnecessary spaces, inconsistent use of single and double quotes, and inline styles that (probably) should be defined in an external stylesheet. -->
  </article>
{% if forloop.counter|divisibleby:3 %}
</div>
<div class="row">
{% endif %}
  {% endfor %}
</div>
Community
  • 1
  • 1
brianpck
  • 8,084
  • 1
  • 22
  • 33
  • hello ok thanks for the answer, but I'm not sure if I understand it correctly. so where do I need to put {% if forloop.counter|divisibleby:3 %}I tried locating it before div class="row" but this gives me error. I tried putting it inside for loop but then it only loops through 3 posts and stop – winixxee Apr 08 '16 at 02:39
  • You need to put the `if` statement in the forloop since it references the counter of the loop. I don't know why it is a problem that it stops after three: you instantiated the `Paginator` object with 3 items per page: `Paginator(newsInCat, 3)` – brianpck Apr 08 '16 at 03:30
  • I'm sorry but the code above is as confusing as mine..//I feel like it's all over the places...maybe I'm just too noobie..and I set it to 25, paginator = Paginator(newsInCat, 25) but this still only gives me three.. – winixxee Apr 08 '16 at 04:01
  • I can't really help you unless you update your question with the code you are currently using. I'm also not clear why the above code is confusing--I opted for different indentation so that the row columns are indented the same, but otherwise you will have to tell me what you don't understand. – brianpck Apr 08 '16 at 13:25
  • sorry it's because of my ignorance, I just set the height of div class = 'col-sm-4' it seems to work...but in mobile whole thing collapses. I figured out how to do pagination as well – winixxee Apr 09 '16 at 13:59
0

I can speak to your HTML/CSS formatting problem. col-sm-4 tells me you're using Bootstrap, which defines layouts in terms of 12 column width. Bootstrap will always attempt to make the with of all rows equal 12.

Right now, you're looping over all the objects and adding n columns each of width col-sm-4. Booststrap is trying to make sure each takes up a third of the row, but you're adding more that 3 divs, which is more than 12 total column width. Once the column is full, (starting with the 4th news item), Bootstrap moves the divs as closely as it can to the top of the row while still obeying the rule that width can only be 12.

In the case you pictured, Bootstrap offsets the 4th and 5th of divs because the offset allows them to be closer to the top of the row.

To fix this, you'd need to have each set of three news items in it's own row, so that your 3 col-sm-4 divs total a width of 12.

  • ok so I see what my problem is...so how do I fix it? hmmm I want every row to col-sm-3 and I thought what I'm doing is for that... – winixxee Apr 08 '16 at 02:28
0

Judging based off the template, you must be still including the full list as well as the paginated set

In your template you are iterating over newsInCat instead of news_set

{% for news in newsInCat %}

should be

{% for news in news_set %}
Sayse
  • 42,633
  • 14
  • 77
  • 146