单击页面按钮后如何防止 Django 表单被重置 [英] How to prevent Django form being reset after clicking page buttons

查看:28
本文介绍了单击页面按钮后如何防止 Django 表单被重置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个从用户那里获取输入值的 Django 表单.然后使用这些值对表 ResourceBase 进行查询,该表最终返回过滤结果列表.

由于结果可能是一个很长的列表,我添加了一个带有上一页"和下一页"按钮的分页功能.我的问题是,当我单击上一个"或下一个"按钮时,表单会恢复为默认值.所有返回的结果都没有了.我如何防止这种情况发生?

我认为当请求不是POST"时,表单会因为form1 = QueryForm()"而被重置.但是,由于我是 Django 和 Web 开发人员的新手,因此我很难想出一个简洁的解决方案.

在views.py中:

定义搜索(请求):如果 request.method == "POST":form1 = QueryForm(data=request.POST)layer_dict = []如果 form1.is_valid():inp_ct = form1.cleaned_data['国家']q1 = ResourceBase.objects.filter(country_name__iexact=inp_ct)对于 q1 中的层:down_url = 'xxxxxxx'.format(layer.title)view_url = 'xxxxxxx'.format(layer.title)layer_dict.append((layer.title, down_url, view_url))layer_dict = sorted(layer_dict, key = lambda x:x[0])paginator = Paginator(layer_dict, 10)page = request.GET.get('page', 1)尝试:层 = paginator.page(page)除了 PageNotAnInteger:# 如果page 不是整数,则传递第一页.层 = paginator.page(1)除了 EmptyPage:# 如果页面超出范围(例如 9999),则提供最后一页的结果.层 = paginator.page(paginator.num_pages)上下文 = {'form1': form1, 'layers': 层}别的:form1 = QueryForm()上下文 = {'form1': form1}返回渲染(请求,'my_app/search.html',上下文)

在 search.html 中:

<br/><h3>分页测试</h3><br/><br/><div class="row"><div class="col-md-4"><表单方法=POST">{% csrf_token %}<div class="form-controls">{{ form1|as_bootstrap }}

<button class="btn btn-primary" type="submit" style="float: right;"title = "点击搜索" ><i class="fa fa-search"></i></button></表单><表单方法=GET"><button class="btn btn-primary" type="submit" value="Reset" name="Reset" title="重置所有选择">重置</button></表单>

{% 如果层数 %}<div class="row"><div class="col-md-8"><div id = "search_results" ><table class="table table-hover"><头><tr><th scope="col">选择</th><th scope="col">层名称</th><th scope="col">下载</th><th scope="col">视图层</th></tr></thead>{% for layer in layer %}<tr><td><input class= messageCheckbox type="checkbox" name="checks" value="{{layer.1}}"/></td><td>{{layer.0}}</td><td><a href="{{layer.1}}" target="_blank">下载层</a></td><td><input class="btn btn-primary" onclick="window.open('{{layer.2}}')" id="view" type="button" name="view" value=查看"></td></tr>{% 结束为 %}<tr><td><input type="checkbox" onClick="toggle(this, 'checks')"/>全选<td></td><td></td><td></td></tr></tbody><button class="btn btn-primary" type="button" name="download" style="float: left;"onClick="open_all_links();">下载选定的</button>

<div class="a_pagination" align="right"><span class="step-links">{% 如果layers.has_previous %}<a class="btn btn-primary btn-sm" name="prev_page" href="?page={{layers.previous_page_number }}" role="button">Prev.</a>{% 万一 %}<span class="current" style="color:#2C689C;font-size:16px;padding:8px;">第 {{layers.number}} 页的 {{layers.paginator.num_pages}}</span>{% 如果layers.has_next %}<a class="btn btn-primary btn-sm" href="?page={{layers.next_page_number }}" role="button">Next</a>{% 万一 %}</span>

{% 万一 %}<script type="text/javascript" >......

解决方案

您不需要使用 POST 方法 将您的参数传递给您的 views.py .按照下面的例子重写你的 view 和你的 html form.这里有一个简单的表单供用户输入搜索词:

<input type="text" name="search4" class="search_input" placeholder="Search" required="required"><input type="submit" value="搜索"></表单>

下一步是您应该检查 views.py 中的输入,我们将输入标签命名为 name="search4" 所以我们检查是否有在我们的 views.py 中使用此代码在我们的表单中输入:

from django.db.models import Q从 django.core.paginator 导入分页器定义搜索(请求):查询 = request.GET.get("search4")如果查询:queryset = ResourceBase.objects.objects.all() # 这将获得模型的所有对象结果 = queryset.filter(Q(country_name__iexact=query)).all()number_of_objects = results.count() # 获取要在 html 文件中显示的确切对象数量paginator = Paginator(results, 12) # 每页显示 12 个联系人page_var = 'page' # 这将用于您的 html 文件中的分页page = request.GET.get(page_var) # 这将用于您的 html 文件中的分页contacts = paginator.get_page(page) # 只发送 12 个对象到您的 html 文件以显示给用户上下文 = {项目":联系人,键":str(查询),页面":page_var,"number_of_objects": number_of_objects,}返回渲染(请求=请求,模板名称=搜索.html",上下文=上下文,内容类型=无,状态=无,使用=无)别的:... # 如果用户没有输入任何内容进行搜索

在您的数据库中获取并搜索用户输入后,您应该在您的 search.html 文件中将其显示给用户,如下所示:

{% for item in items %}<div><div><div class="product_title">{{ item.title }}</div># 显示您希望用户看到的部分... # 要显示的其余项目部分

{% 结束为 %}<div class="分页"><span class="step-links">{% if items.has_previous %} # 检查分页是否有旧页<a href="?{{ page }}=1">«首先<a href="?{{ page }}={{ items.previous_page_number }}">previous</a>{% 万一 %}<span class="current">第 {{ items.number }} of {{ items.paginator.num_pages }} # 结果示例:第 1 页,共 13 页</span>{% if items.has_next %}<a href="?{{ page }}={{ items.next_page_number }}"</a># 检查分页是否有下一页或上一页<a href="?{{ page }}={{ items.paginator.num_pages }}">last &raquo;</a># 指向最后一页的链接{% 万一 %}</span>{{ 分页 }}

这是一个带有分页器的基本搜索页面,如果您需要任何进一步的帮助或问题,我将很乐意提供帮助.

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 the results might be a long list, I added a pagination function with "Prev" and "Next" buttons. My problem is that when I click "Prev" or "Next" button, the form gets restored into default values. And all returned results are all gone. How do I prevent this from happening?

I think the form gets reset because of "form1 = QueryForm()" when a request is not "POST". However I just have difficulty coming up with a neat solution since I'm new to Django and web dev.

In views.py:


def search(request):

    if request.method == "POST":

        form1 = QueryForm(data=request.POST)

        layer_dict = []

        if form1.is_valid():

            inp_ct = form1.cleaned_data['country']

            q1 = ResourceBase.objects.filter(country_name__iexact=inp_ct)

            for layer in q1:

                down_url = 'xxxxxxx'.format(layer.title)
                view_url = 'xxxxxxx'.format(layer.title)
                layer_dict.append((layer.title, down_url, view_url))

            layer_dict = sorted(layer_dict, key = lambda x:x[0])

            paginator = Paginator(layer_dict, 10)

            page = request.GET.get('page', 1)

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

            context = {'form1': form1, 'layers': layers}

    else:

        form1 = QueryForm()

        context = {'form1': form1}


    return render(request, 'my_app/search.html', context)


In search.html:

<br />
<h3>Pagination Test</h3>
<br /><br/>


<div class="row">
    <div class="col-md-4">
        <form method="POST">
            {% csrf_token %}

              <div class="form-controls">
                {{ form1|as_bootstrap }}
              </div>
            <button class="btn btn-primary" type="submit" style="float: right;" title = "Click to search" ><i class="fa fa-search"></i></button>
        </form>

        <form method="GET">
            <button class="btn btn-primary" type="submit" value="Reset" name="Reset" title="Reset all choices">Reset</button>
        </form>
    </div>
</div>


{% if layers %}

<div class="row">

    <div class="col-md-8">

        <div id = "search_results" >

            <table class="table table-hover">
              <thead>
                <tr>
                  <th scope="col">Select</th>
                  <th scope="col">Layer Name</th>
                  <th scope="col">Download</th>
                  <th scope="col">View Layer</th>
                </tr>
              </thead>

              <tbody>
                {% for layer in layers %}
                <tr>
                  <td><input class= messageCheckbox type="checkbox" name="checks" value="{{layer.1}}"/></td>
                  <td>{{layer.0}}</td>
                  <td><a href="{{layer.1}}" target="_blank"> Download Layer </a></td>
                  <td><input class="btn btn-primary" onclick="window.open('{{layer.2}}')" id="view" type="button" name="view" value="View"></td>
                </tr>
                {% endfor %}

                <tr>
                    <td><input type="checkbox" onClick="toggle(this, 'checks')"/> Select All</td>
                    <td></td>
                    <td></td>
                    <td></td>
                </tr>

              </tbody>
            </table>

            <button class="btn btn-primary" type="button" name="download" style="float: left;" onClick= "open_all_links();">Download Selected</button>

        </div>


     <div class="a_pagination" align="right">
            <span class="step-links">

                {% if layers.has_previous %}

                    <a class="btn btn-primary btn-sm" name="prev_page" href="?page={{ layers.previous_page_number }}" role="button">Prev.</a>
                {% endif %}

                <span class="current" style ="color:#2C689C;font-size:16px;padding:8px;">
                    page {{ layers.number }} of {{ layers.paginator.num_pages }}
                </span>

                {% if layers.has_next %}
                    <a class= "btn btn-primary btn-sm"  href="?page={{ layers.next_page_number }}" role="button">Next</a>

                {% endif %}

            </span>
        </div>
    </div>
</div>

{% endif %}

<script type="text/javascript" >
.......
</script>

解决方案

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="">
    <input type="text" name="search4" class="search_input" placeholder="Search" required="required">                                       
    <input type="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

def search(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.

这篇关于单击页面按钮后如何防止 Django 表单被重置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
Python最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆