0

I want to count the objects in my template, but since I am using pagination to divide them into pages, I want to use counter from different object_list than the one used in the for loop.

This is my template:

{% extends 'base.html' %}
{% block content %}
    {% if user.is_superuser %}
    <div class="row">
        <div class="col-sm-4 offset-sm-4">
            <form class="form-inline md-form form-sm" method="GET" action="">
            <i class="fa fa-search" aria-hidden="true"></i>
            <input class="form-control form-control-sm ml-3 w-75" type="text" placeholder="搜索货品 Znajdź część" name="q" value="{{ request.GET.q }}"/>
            </form>
        </div>
    </div>
    <br/>
    <hr/>
    <div class='row'>
        <table class="table">
            <thead class="thead-dark">
                <tr>
                  <th scope="col">#</th>
                  <th scope="col">Image</th>
                  <th scope="col">Product name</th>
                  <th scope="col">Price (cost)</th>
                  <th scope="col">Price (PL)</th>
                </tr>
            </thead>
            <tbody>
                {% for product in objects %}
                    <tr>
                      <th scope="row">{{forloop.counter}}</th>
                      <td><img class="img img-fluid rounded" width="200" height="136" src="{{ product.photo.url }}"></td>
                      <td>{{product.product_name}}</td>
                      <td>{{product.price}}</td>
                      <td>{{product.price_pol}}</td>
                    </tr>
                {% endfor %}
            </tbody>
        </table>
        </div>
        <div class="col-sm-4 offset-sm-4" align="center">
            <div class="pagination">
                <span class="step-links">
                    {% if objects.has_previous %}
                        <a href="?page=1">&laquo; first</a>
                        <a href="?page={{ objects.previous_page_number }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">previous</a>
                    {% endif %}

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

                    {% if objects.has_next %}
                        <a href="?page={{ objects.next_page_number }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">next</a>
                        <a href="?page={{ objects.paginator.num_pages }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">last &raquo;</a>
                    {% endif %}
                </span>
            </div>
        </div>
    {% endif %}
{% endblock content %}

My views.py:

Here I would like to use counter from object_list and not object (Note the context in productview)

@login_required
def productview(request):
    object_list = Product.objects.all().order_by('-date')
    query = request.GET.get('q')
    if query:
        object_list = object_list.filter(
            Q(product_name__icontains=query)|
            Q(date__icontains=query)
            ).distinct()
    paginator = Paginator(object_list, 5)
    page = request.GET.get('page')
    objects = paginator.get_page(page)

   return render(request, 'products_list.html', {'objects': objects, 'object_list':object_list})

I wanted to use the nested loop, but it didn't work out. Is there another way that I don't know of? If I leave it like this every time I click nextpage the counter will start from "1". I would like the counter to continue when I click the next page...

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
seba6m6
  • 109
  • 1
  • 12

1 Answers1

0

You can enumerate you obect_list:

def productview(request):
    object_list = Product.objects.all().order_by('-date')
    query = request.GET.get('q')
    if query:
        object_list = object_list.filter(
            Q(product_name__icontains=query)|
            Q(date__icontains=query)
            ).distinct()
    object_list =list(enumerate(object_list))
    paginator = Paginator(object_list, 5)
    page = request.GET.get('page')
    objects = paginator.get_page(page)

   return render(request, 'products_list.html', {'objects': objects, 'object_list':object_list})

Then the structure of the objects has changed: product.0 will contain the counter and product.1 will contain the model instance:

  {% for product in objects %}
                <tr>
                  <th scope="row">{{product.0}}</th>
                  <td><img class="img img-fluid rounded" width="200" height="136" src="{{ product.1.photo.url }}"></td>
                  <td>{{product.1.product_name}}</td>
                  <td>{{product.1.price}}</td>
                  <td>{{product.1.price_pol}}</td>
                </tr>
            {% endfor %}
ger.s.brett
  • 3,267
  • 2
  • 24
  • 30
  • I got this : #012TypeError: object of type 'enumerate' has no len() . But the object_list actually has items in it – seba6m6 Oct 01 '18 at 05:30
  • I guess you need to make a list out of it - see edit. – ger.s.brett Oct 01 '18 at 08:10
  • It actually works but i still dont know how it works. Can you tell me why enumeration of 'object_list' was assigned to {{product.0}} when in context i actually put it in the second place. Is there any tutorials that explain it ? and the second thing is that enumeration starts with "0".. How can i specify it in the code so that enumeration starts with "1" ?? Cheers.. – seba6m6 Oct 07 '18 at 14:58
  • ok, found how to do it. " object_list =list(enumerate(object_list, 1)) " - solves the problem. Still don't know how work the ".0" and ".1." that you used in the template... lol Any links with the explanation . I am super curious about that – seba6m6 Oct 08 '18 at 02:35
  • https://stackoverflow.com/questions/4651172/reference-list-item-by-index-within-django-template – ger.s.brett Oct 08 '18 at 11:05