Django ListView - 用于过滤和排序的表单

Roo*_*rle 14 forms sorting django listview filter

我的目标

  • 列出表中所有更新(模型)的站点
  • 不要一次显示所有模型(分页 - 每页10个)
  • 过滤并对列表进行排序

我的想法

  • 我可以使用ListView获取一组所有更新
  • 使用paginate_by = 10
  • 使用表单在我的QuerySet中设置order_by或filter

我的问题

我不知道如何使用过滤器和排序添加表单来修改我的QuerySet.我的想法是使用额外的filter和order_by修改get_queryset中的Query.

我的看法

class MyView(ListView):
    model = Update
    template_name = "updates/update.html"
    paginate_by = 10

    def get_queryset(self):
        return Update.objects.filter(
            ~Q(state=Update.STATE_REJECTED),
            ~Q(state=Update.STATE_CANCELED),
            ~Q(state=Update.STATE_FINISHED),
        ).order_by(
            'planned_release_date'
        )
Run Code Online (Sandbox Code Playgroud)

我的想法

像这样的东西.我知道这不是这样的工作......只是为了说明

class MyView(ListView):
    model = Update
    template_name = "updates/update.html"
    paginate_by = 10

    def post(self, request, *args, **kwargs):
        new_context = Update.objects.filter(
            request.POST.get("filter"),
        ).order_by(
            request.POST.get("sorting"),
        )

    def get_queryset(self):
        return Update.objects.filter(
            ~Q(state=Update.STATE_REJECTED),
            ~Q(state=Update.STATE_CANCELED),
            ~Q(state=Update.STATE_FINISHED),
        ).order_by(
            'planned_release_date'
        )
Run Code Online (Sandbox Code Playgroud)

Anu*_*dra 24

你不需要发帖.在网址中传递过滤器值和order_by,例如:

.../update/list/?filter=filter-val&orderby=order-val

并在get_queryset中获取过滤器和orderby,如:

class MyView(ListView):
    model = Update
    template_name = "updates/update.html"
    paginate_by = 10

    def get_queryset(self):
        filter_val = self.request.GET.get('filter', 'give-default-value')
        order = self.request.GET.get('orderby', 'give-default-value')
        new_context = Update.objects.filter(
            state=filter_val,
        ).order_by(order)
        return new_context

    def get_context_data(self, **kwargs):
        context = super(MyView, self).get_context_data(**kwargs)
        context['filter'] = self.request.GET.get('filter', 'give-default-value')
        context['orderby'] = self.request.GET.get('orderby', 'give-default-value')
        return context
Run Code Online (Sandbox Code Playgroud)

确保为filter和orderby提供正确的默认值

示例表单(您可以根据需要进行修改):

<form method="get" action="{% url 'update-list' %}">
    <p>Filter: <input type="text" value={{filter}} name="filter"/></p>
    <p>order_by: <input type="text" value={{orderby}} name="orderby"/></p>
    <p><input type="submit" name="submit" value="submit"/></p>
</form>
Run Code Online (Sandbox Code Playgroud)


and*_*abs 6

我想知道为什么没人在这里提到这个很酷的库:https : django-filter //github.com/carltongibson/django-filter

您可以定义过滤非常干净的逻辑并获得快速的工作表格等。

演示在这里:https : //stackoverflow.com/a/46492378/953553


She*_*erd 5

我在别处发布了这个,但我认为这增加了所选的答案。

我认为您最好通过 get_context_data 执行此操作。手动创建 HTML 表单并使用 GET 检索此数据。下面是我写的一个例子。当您提交表单时,您可以使用获取数据通过上下文数据传回。此示例不是针对您的请求量身定制的,但它应该可以帮助其他用户。

def get_context_data(self, **kwargs):
    context = super(Search, self).get_context_data(**kwargs)
    filter_set = Gauges.objects.all()
    if self.request.GET.get('gauge_id'):
        gauge_id = self.request.GET.get('gauge_id')
        filter_set = filter_set.filter(gauge_id=gauge_id)

    if self.request.GET.get('type'):
        type = self.request.GET.get('type')
        filter_set = filter_set.filter(type=type)

    if self.request.GET.get('location'):
        location = self.request.GET.get('location')
        filter_set = filter_set.filter(location=location)

    if self.request.GET.get('calibrator'):
        calibrator = self.request.GET.get('calibrator')
        filter_set = filter_set.filter(calibrator=calibrator)

    if self.request.GET.get('next_cal_date'):
        next_cal_date = self.request.GET.get('next_cal_date')
        filter_set = filter_set.filter(next_cal_date__lte=next_cal_date)

    context['gauges'] = filter_set
    context['title'] = "Gauges "
    context['types'] = Gauge_Types.objects.all()
    context['locations'] = Locations.objects.all()
    context['calibrators'] = Calibrator.objects.all()
    # And so on for more models
    return context
Run Code Online (Sandbox Code Playgroud)