0

view.py

def quiz(request):

    question_topic = request.POST.getlist("topic_checkbox") # Retrieves list of topics selected by user
    question_list = Quiz.objects.filter(Topic_name__in = question_topic) #filters out questions by topics

    paginator = Paginator(question_list,1) # when i pass all the objects rather than the filtered query set it seems to work but when i paginate with the filtered queryset only the first page loads
    page = request.GET.get('page')
    try:
        question_list = paginator.page(page)
    except PageNotAnInteger:
        question_list = paginator.page(1)
    except EmptyPage:
        question_list = paginator.page(paginator.num_pages)

    return render(request,"Quiz/quiz_home.html",{"question_list":question_list})

quiz_home.html

{% block content %}
        {% for q in question_list %} # loops through the filtered queryset
            {% if question_list.has_next %}
                <h3>Question {{q.id}}</h3>
                <form method="POST" action="?page={{ question_list.next_page_number }}">{% csrf_token %}
# The form should enable me to gather the users input whilst simultaneoulsy going to the next question in the for loop. But when question sumbitted the next page is blank showing no contents
                    {% if q.picture %}
                        <img src="/media/{{q.picture}}"> <br>
                    {% endif %}
                    {{q.id}}.) </label><label id="question_text">{{q.question}}</label><br>
                    <input type="hidden" id= "q_id" name="q_id" value="{{q.id}}">
                    <input type="hidden" id= "topic" name="topic" value="{{q.topic}}">
                    <input type="radio" id="opt1" name="options" value="{{q.option1}}" required>{{ q.option1 }}<br>
                    <input type="radio" id="opt2" name="options" value="{{q.option2}}" required>{{ q.option2 }}<br>
                    <input type="radio" id="opt3" name="options" value="{{q.option3}}" required>{{ q.option3 }}<br>
                    <hr>
                    <input type="submit" id="mybtn" value="Submit"> #once clicked it should paginate to next page
                </form>
            {% else %}
                <hr>
                <form action="/home/">{% csrf_token %}
                    <input type="submit" name="End" value="End">
                </form>
            {% endif %}
        {% endfor %}
    {% endblock %}

Essentially im trying to filter out questions based on what topics the user has selected. This queryset of questions is then paginated so that each page shows one question.

1 Answers1

0

I'll show you a pagination instance:

views.py

class CategoryDetail(ListView):  
    model = Task  
    template_name = 'category/category_detail.html'  
    context_object_name = 'task'  
    paginate_by = 5

    def get_queryset(self):
        self.category = get_object_or_404(Category,
                                          pk=self.kwargs['pk'])  
        return Task.objects.filter(category=self.category).order_by('-id')  

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super(CategoryDetail, self).get_context_data(**kwargs)
        self.category = get_object_or_404(Category, pk=self.kwargs['pk'])
        # context['category'] = self.category
        return context

category/category_detail.html

....

 <div class="card-footer py-4">
                {% if is_paginated %}
              <nav aria-label="...">
                <ul class="pagination justify-content-end mb-0">
                    {% if page_obj.has_previous %}
                  <li class="page-item">
                    <a class="page-link" href="?page={{ page_obj.previous_page_number }}" tabindex="-1">
                      <i class="fas fa-angle-left"></i>
                      <span class="sr-only">Previous</span>
                    </a>
                  </li>

                   {% else %}

                     <li class="page-item disabled">
                    <a class="page-link" href="#" tabindex="-1">
                      <i class="fas fa-angle-left"></i>
                      <span class="sr-only">Previous</span>
                    </a>
                  </li>

                    {% endif %}

                    {% for i in paginator.page_range %}
                    {% if page_obj.number == i %}
                  <li class="page-item active">
                    <a class="page-link" href="#"> {{ i }} </a>
                  </li>
                     {% else %}
                  <li class="page-item">
                    <a class="page-link" href="?page={{ i }}">{{ i }}<span class="sr-only">(current)</span></a>
                  </li>
                    {% endif %}
                    {% endfor %}

                     {% if page_obj.has_next %}
                  <li class="page-item">
                    <a class="page-link" href="?page={{ page_obj.next_page_number }}">
                      <i class="fas fa-angle-right"></i>
                      <span class="sr-only">Next</span>
                    </a>
                  </li>

                    {% else %}

                     <li class="page-item disabled">
                    <a class="page-link" href="#">
                      <i class="fas fa-angle-right"></i>
                      <span class="sr-only">Next</span>
                    </a>
                  </li>
                    {% endif %}

                </ul>
              </nav>
                {% endif %}
            </div>

Django already has a ready-made paging structure. You can use it in your Html file you want to use.

Ayse
  • 576
  • 4
  • 13
  • ListView doesn't work when we have forms right? I'm trying to paginate the filtered queryset question_list = Quiz.objects.filter(Topic_name__in = question_topic) whilst also posting data from each page. An example of this using function based views would be appreciated. – seif sultan Oct 28 '20 at 12:17