Skip to content Skip to sidebar Skip to footer

How To Prevent Django Form Being Reset After Clicking Page Buttons

I have a Django form that takes input values from users. The values are then used in making query to a table ResourceBase, which finally returns a list of filtered results. Since t

Solution 1:

You don't need to use POST Method to pass your arguments to your views.py . Follow the below example and rewrite your view and your html form. here a simple form for user to enter the word for search:

<form method="get" action="">
    <inputtype="text" name="search4" class="search_input" placeholder="Search" required="required">                                       
    <inputtype="submit" value="Search">
</form>

The next step is that you should check the input in your views.py, we named the input tage name="search4" so we check if there is any input in our form using this code in our views.py:

from django.db.models import Q
from django.core.paginator import Paginator

defsearch(request):
    query = request.GET.get("search4")
    if query:
        queryset = ResourceBase.objects.objects.all() # this will get all of your object of your model
        results = queryset.filter(Q(country_name__iexact=query)).all() 
        number_of_objects = results.count() # get the exact number of object to show in your html file
        paginator = Paginator(results, 12)  # Show 12 contacts per page
        page_var = 'page'# this will use for pagination in your html file
        page = request.GET.get(page_var) # this will use for pagination in your html file
        contacts = paginator.get_page(page)  # send only 12 object to your html file to show to user
         context = {
            "items": contacts,
            "key": str(query),
            'page': page_var, 
            "number_of_objects": number_of_objects,
        }
        return render(request=request, template_name='search.html', context=context, content_type=None, status=None,
                  using=None)
    else:
        ... # if user didn't enter anything to search

After getting and searching the user input in your data base, You should show it to user in your search.html file like this:

{% for item  in items %}
<div>
    <div>
            <div class="product_title">{{ item.title }}</div> # show the part that you want the users to see
            ...                                               # rest of your item parts to show
    </div>
</div>
{% endfor %}

<div class="pagination">
                    <span class="step-links">
                        {% if items.has_previous %} # check the pagination that if there is perivious pages 
                            <a href="?{{ page }}=1">&laquo; first</a>

                            <a href="?{{ page }}={{ items.previous_page_number }}">previous</a>
                        {% endif %}

                        <span class="current">
                            Page {{ items.number }} of {{ items.paginator.num_pages }} # example of result : Page 1 of 13
                        </span>

                        {% if items.has_next %}
                            <a href="?{{ page }}={{ items.next_page_number }}"</a> # check the pagination that if there is any next or perivious pages 

                            <a href="?{{ page }}={{ items.paginator.num_pages }}">last &raquo;</a> # a link to last page
                        {% endif %}
                    </span>
                    {{ pagination }}

this is a basic search page with Paginator, if you need any further help or question, I will be happy to help.

Solution 2:

The code <a class= "btn btn-primary btn-sm" href="?page={{ layers.next_page_number }}" role="button">Next</a> will indeed GET the page and the form1 = QueryForm() code will result in empty form. You are on a right track here.

You have two options:

1) Change the next/prev buttons so that they are inside the form1 form and they POST stuff. It might be challenging to move them inside the same form tag.

If you target modern browsers you can use HTML5 form tag in submit (https://www.w3schools.com/tags/att_button_form.asp).

<formmethod="POST"id="form1">
    {{ form1|as_bootstrap }}
</form>
 ... outside the form tag, then
<buttonclass="btn btn-primary btn-sm"form="form1"name="next"value="{{ layers.next_page_number }}"role="button">Next</button>

You should have in request.POST the next value.

2) Initialize the QueryForm from GET params.

form1 = QueryForm(data=request.GET)

and include the form parameters into the url. For this you would need some Javascript (for example How to use an input field as query parameter to a destination?) as Django doesn't know about the values in the form on rendering time before user inserts them.

Solution 3:

You can change the pagination links into buttons to submit the form. More detailed answer in here: How to define which input fields the form has by pressing different buttons?

You can read my comment on the answer. It explains how the answer can be helpful in pagination.

I modified the pagination code I found in https://simpleisbetterthancomplex.com/series/2017/10/09/a-complete-beginners-guide-to-django-part-6.html The modified code for pagination is also as below:

<navaria-label="Topics pagination"class="mb-4"><ulclass="pagination">
    {% if page_obj.has_previous %}
      <liclass="page-item"><buttonform="my_form"name="page"value="{{page_obj.number|add:'-1'}}"role="button"class="btn btn-link">Previous</button></li>
    {% else %}
      <liclass="page-item disabled"><spanclass="page-link">Previous</span></li>
    {% endif %}

    {% for i in page_obj.paginator.page_range %}

      {% if page_obj.number == i %}
        <liclass="page-item active"><spanclass="page-link">
            {{ i }}
            <spanclass="sr-only">(current)</span></span></li>
      {% else %}
        <liclass="page-item"><buttonform="my_form"name="page"value="{{i}}"role="button"class="btn btn-link">{{ i }}</button></li>
      {% endif %}
    {% endfor %}

    {% if page_obj.has_next %}
      <liclass="page-item"><buttonform="my_form"name="page"value="{{page_obj.number|add:1}}"role="button"class="btn btn-link">Next</button></li>
    {% else %}
      <liclass="page-item disabled"><spanclass="page-link">Next</span></li>
    {% endif %}
  </ul></nav>>

Post a Comment for "How To Prevent Django Form Being Reset After Clicking Page Buttons"