首页 > 解决方案 > 有没有办法在 django generic ListView 中执行 django admin 之类的列表过滤?

问题描述

我正在尝试为 django 列表视图添加过滤,例如在此处输入图像描述

这是我的看法

class SaleView(ListView):
    model = SaleBill
    template_name = "sales/sales_list.html"
    context_object_name = "bills"
    ordering = ["-time"]
    paginate_by = 10

和我的模板

{% extends "base.html" %}

{% load widget_tweaks %}


{% block title %} Sales List {% endblock title %}


{% block content %}

    <div class="row" style="color: #ea2088; font-style: bold; font-size: 3rem;">
        <div class="col-md-8">Sales List</div>
        <div class="col-md-4">
            <div style="float:right;"> <a class="btn ghost-blue" href="{% url 'new-sale' %}">New Outgoing Stock</a> </div>
        </div>
    </div>

    <br>

    <table class="table table-css">

        <thead class="thead-inverse align-middle">
            <tr>
                <th width="10%">Bill No</th>
                <th width="15%">Customer</th>
                <th width="15%">Stocks Sold</th>
                <th width="10%">Quantity Sold</th>
                <th width="10%">Total Sold Price</th>
                <th width="15%">Sale Date</th>
                <th width="25%">Options</th>
            </tr>
        </thead>

{% if bills %}

        <tbody>
            {% for sale in bills %}
            <tr>
                <td class="align-middle"> <h3>{{ sale.billno }}</h3> </td>
                <td class=""> {{ sale.name }} <br> <small style="color: #909494">Ph No : {{ sale.phone }}</small> </td>
                <td class="align-middle">{% for item in sale.get_items_list %} {{ item.stock.name }} <br> {% endfor %}</td>
                <td class="align-middle">{% for item in sale.get_items_list %} {{ item.quantity }} <br> {% endfor %}</td>
                <td class="align-middle">{{ sale.get_total_price }}</td>
                <td class="align-middle">{{ sale.time.date }}</td>
                <td class="align-middle"> <a href="{% url 'sale-bill' sale.billno %}" class="btn ghost-pink">View Bill</a> <a href="{% url 'delete-sale' sale.pk %}" class="btn ghost-red">Delete Bill</a> </td>
            </tr>
            {% endfor %}
        </tbody>

    </table>

    <div class="align-middle">
        {% if is_paginated %}

            {% if page_obj.has_previous %}
                <a class="btn btn-outline-info mb-4" href="?page=1">First</a>
                <a class="btn btn-outline-info mb-4" href="?page={{ page_obj.previous_page_number }}">Previous</a>
            {% endif %}

            {% for num in page_obj.paginator.page_range %}
                {% if page_obj.number == num %}
                    <a class="btn btn-info mb-4" href="?page={{ num }}">{{ num }}</a>
                {% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
                    <a class="btn btn-outline-info mb-4" href="?page={{ num }}">{{ num }}</a>
                {% endif %}
            {% endfor %}

            {% if page_obj.has_next %}
                <a class="btn btn-outline-info mb-4" href="?page={{ page_obj.next_page_number }}">Next</a>
                <a class="btn btn-outline-info mb-4" href="?page={{ page_obj.paginator.num_pages }}">Last</a>
            {% endif %}

        {% endif %}
    </div>

{% else %}

        <tbody></tbody>
    </table>

    <br><br><br><br><br><br><br><br>
    <div style="color: #ea2088; font-style: bold; font-size: 1.5rem; text-align: center;">WOW, SUCH EMPTY</div>

{% endif %}

{% endblock content %}

我看过Django 代码

而且我不确定这是添加此功能的唯一方法还是有更简单的方法。

标签: djangodjango-viewsdjango-formsdjango-filter

解决方案


更简单的方法?的。您只需要覆盖get_queryset列表视图的方法。

class SaleView(ListView):
    model = SaleBill
    template_name = "sales/sales_list.html"
    context_object_name = "bills"
    ordering = ["-time"]
    paginate_by = 10
    
    def get_queryset(self):
    # Here we try to filter by status
    status = self.kwargs.get('ststus', None)
    # If a the key 'status' is set in the url
    if status:
        if status == 'new':
            return super(SaleView, self).get_queryset().filter(
                status='new')
        elif status == 'open':
            return super(SaleView, self).get_queryset().filter(
                status='open')
        else:  # the last status is 'canceled'
            return super(SaleView, self).get_queryset().filter(
                status='canceled')
    else:  # The key status is not set in the url
        # Return the default queryset without filter
        return super(SaleView, self).get_queryset()

template.html 这是您可以呈现这些不同链接的方式

<ul class='filter'>
    <!-- This one is the default (no filter) -->
    <li><a href="{% url 'list_view' status='' %}">All</a></li>
    <!-- Others filter option (no filter) -->
    <li><a href="{% url 'list_view' status='new' %}">New</a></li>
    <li><a href="{% url 'list_view' status='open' %}">Open</a></li>
    <li><a href="{% url 'list_view' status='canceled' %}">Canceled</a></li>
</ul>

所以根据你的需要改变它。


推荐阅读