Django ListView 自定义查询集 [英] Django ListView customising queryset

查看:29
本文介绍了Django ListView 自定义查询集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

希望这应该是一个简单的帮助我.

我有一个包含三个项目的下拉菜单的页面:

<选择名称=浏览"><option>猫</option><option>狗</option><option>蠕虫</option></选择><input type="submit" value="Submit"/></表单><!-- 输出表--><table id="myTable"><头><tr><th>姓名</th><th>颜色</th></tr></thead>{% 用于 object_list 中的对象 %}<tr><td>{{object.name }}</td><td>{{object.colour }}</td></tr>{% 结束为 %}</tbody><!-- 分页控件--><div class="分页"><span class="page-links">{% if page_obj.has_previous %}<a href="?page={{ page_obj.previous_page_number }}">previous</a>{% 万一 %}<span class="page-current">第 {{ page_obj.number }} 页,共 {{ page_obj.paginator.num_pages }}.</span>{% if page_obj.has_next %}<a href="?page={{ page_obj.next_page_number }}">next</a>{% 万一 %}</span>

当用户选择一个项目并点击提交时,他们会在由通用 ListView 生成的表格中获得结果:

class Browse(generic.ListView):模板名称 = 'app/browse.html'paginate_by = 25def get_queryset(self):查询集 = Cats.objects.all()如果 self.request.GET.get("browse"):selection = self.request.GET.get("浏览")如果选择==猫":查询集 = Cats.objects.all()elif 选择 ==狗":查询集 = Dogs.objects.all()elif 选择 ==蠕虫":查询集 = Worms.objects.all()别的:查询集 = Cats.objects.all()返回查询集

但是,当我尝试使用分页控件翻页时,查询集会重置为第一项(默认)Cats,因为(我认为)表单数据已重置.

知道如何规避这个问题吗?

谢谢!

PS:哦,在那个注意事项中,是否可以将查询集设置为无一开始?非常感谢!

更新:当我在 Cats 查询集上使用分页时,它工作正常,因此该错误仅显示在其他两组上.

解决方案

为了解决这个问题,我只是修改了分页 HTML,以适应来自表单的 get 请求和 url 字符串中的页码,如下所示:

这里的 {{ input }} 是一个包含通过表单提交的选项的字符串,例如猫"或蠕虫".

为了能够将其传递到模板中,我修改了基于类的视图的 get_context_data 方法,如下所示:

class Browse(generic.ListView):模板名称 = 'app/browse.html'paginate_by = 25# 修改get_context_data方法def get_context_data(self, **kwargs):context = super(Browse, self).get_context_data(**kwargs)q = self.request.GET.get("浏览")上下文['输入'] = q返回上下文def get_queryset(self):查询集 = Cats.objects.all()如果 self.request.GET.get("browse"):selection = self.request.GET.get("浏览")如果选择==猫":查询集 = Cats.objects.all()elif 选择 ==狗":查询集 = Dogs.objects.all()elif 选择 ==蠕虫":查询集 = Worms.objects.all()别的:查询集 = Cats.objects.all()返回查询集

就是这样,url 字符串现在是这样的:

/browse/?browse=Cats&page=3

就是这样,分页现在可以与表单的 get 方法一起使用了.

Hopefully this should be a simple one to help me with.

I have a page with a dropdown menu containing three items:

<form method="GET">

    <select name="browse">

        <option>Cats</option>

        <option>Dogs</option>

        <option>Worms</option>

    </select>

 <input type="submit" value="Submit" />

</form>

<!-- Output table -->

  <table id="myTable">

      <thead>
          <tr>
            <th>Name</th>
            <th>Colour</th>
          </tr>
      </thead>

      <tbody>
      {% for object in object_list %}
          <tr>
            <td>{{ object.name }}</td>
            <td>{{ object.colour }}</td>
          </tr>
      {% endfor %}
      </tbody>

  </table>

<!-- Pagination controls -->

<div class="pagination">
    <span class="page-links">
        {% if page_obj.has_previous %}
            <a href="?page={{ page_obj.previous_page_number }}">previous</a>
        {% endif %}
        <span class="page-current">
            Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
        </span>
        {% if page_obj.has_next %}
            <a href="?page={{ page_obj.next_page_number }}">next</a>
        {% endif %}
    </span>
</div>

When the user selects an item and hits submit, they are given the results in a table as generated by the generic ListView:

class Browse(generic.ListView):
    template_name = 'app/browse.html'
    paginate_by = 25

    def get_queryset(self):
        queryset = Cats.objects.all()
        if self.request.GET.get("browse"):
            selection = self.request.GET.get("browse")
            if selection == "Cats":
                queryset = Cats.objects.all()
            elif selection == "Dogs":
                queryset = Dogs.objects.all()
            elif selection == "Worms":
                queryset = Worms.objects.all()
            else:
                queryset = Cats.objects.all()
        return queryset

However, when I attempt to turn a page using the pagination controls, the queryset resets to the first (default) item Cats, because (I think) the form data is reset.

Any idea how to circumvent this problem?

Thanks!

PS: Oh, on that note, is it possible to set the queryset to none to begin with? Much obliged!

UPDATE: When I use pagination on the Cats queryset it works fine so the bug is only displayed on the other two sets.

解决方案

To solve this problem I just modified the pagination HTML, to accommodate both the get request from the form and the page number in the url string, like so:

<div class="pagination">
    <span class="page-links">
        {% if page_obj.has_previous %}
            <a href="/browse/?browse={{ input }}&page={{ page_obj.previous_page_number }}">previous</a>
        {% endif %}
        <span class="page-current">
            Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
        </span>
        {% if page_obj.has_next %}
            <a href="/browse/?browse={{ input }}&page={{ page_obj.next_page_number }}">next</a>
        {% endif %}
    </span>
</div>

The {{ input }} here is a string containing the option submitted via the form, e.g. 'Cats' or 'Worms'.

To be able to pass this into the template, I modified the get_context_data method of the class based view as such:

class Browse(generic.ListView):
    template_name = 'app/browse.html'
    paginate_by = 25

    # Modifying the get_context_data method

    def get_context_data(self, **kwargs):
        context = super(Browse, self).get_context_data(**kwargs)
        q = self.request.GET.get("browse")
        context['input'] = q
        return context

    def get_queryset(self):
        queryset = Cats.objects.all()
        if self.request.GET.get("browse"):
            selection = self.request.GET.get("browse")
            if selection == "Cats":
                queryset = Cats.objects.all()
            elif selection == "Dogs":
                queryset = Dogs.objects.all()
            elif selection == "Worms":
                queryset = Worms.objects.all()
            else:
                queryset = Cats.objects.all()
        return queryset

That was it, the url string now reads something like:

/browse/?browse=Cats&page=3

So there it is, pagination now works alongside the get method of the form.

这篇关于Django ListView 自定义查询集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆