首页 > 解决方案 > Django将表单中的数据过滤到另一个视图

问题描述

我似乎无法做到这一点,而且我几乎查看了所有喜欢的帖子。现在我不知道我的代码在做什么。我有一个索引页,它有一个小表格。我只想用这个表格来查询我的数据库并过滤结果。我在另一个页面上使用了 django-filters,它工作得很好,但我似乎无法将数据从我的索引页面的表单传递到下一个视图。这是我的代码:

网址.py

from django.urls import path
from .views import IndexView
from . import views

urlpatterns = [
    path('', IndexView.as_view(), name='index'),
    path('search/', views.search, name='search'),
]

视图.py

from django.db.models import Max, Min
from django.shortcuts import render
from django.views.generic import FormView

from .filters import ProductFilter
from .forms import ProductSearchForm
from .models import LengthRange, Hull, PowerConfiguration, SpeedRange, Product


class IndexView(FormView):
    template_name = 'index.html'
    form_class = ProductSearchForm
    success_url = "search/"

    def get_context_data(self, **kwargs):
        context = super(IndexView, self).get_context_data(**kwargs)
        context['length_ranges'] = LengthRange.objects.all().order_by('pk')
        context['hull_types'] = Hull.objects.all().order_by('pk')
        context['power_configs'] = PowerConfiguration.objects.all().order_by('pk')
        context['speed_ranges'] = SpeedRange.objects.all().order_by('pk')
        context['price'] = Product.objects.all().aggregate(Min('price'), Max('price'))
        return context

    def form_valid(self, form):
        # This method is called when valid form data has been POSTed.
        # It should return an HttpResponse.
        # form.send_email()
        # print "form is valid"
        return super(IndexView, self).form_valid(form)


def search(request):
    product_list = Product.objects.all()
    product_filter = ProductFilter(request.GET, queryset=product_list)
    return render(request, 'product_list.html', {'filter': product_filter})

表格.py

from django.forms import ModelForm
from .models import Product


class ProductSearchForm(ModelForm):
    class Meta:
        model = Product
        fields = ('length_range', 'hull_type', 'price', 'power', 'speed', 'hull_only_available')

product_list.html

{% load humanize %}
<html>
<form method="get">
    {{ filter.form.as_p }}
    <button type="submit">Search</button>
  </form>
  <ul>
  {% for product in filter.qs %}
    <li>{{ product.vendor }} {{ product.product_model }} - ${{ product.price|intcomma }}</li>
  {% endfor %}
  </ul>
</html>

索引.html

<form class="nl-form" action="{% url 'boatsales:search' %}" method="post">
                            {% csrf_token %}
                                A boat with a length of
                                <select>
                                    <option value="*" selected>any size</option>
                                    {% for length in length_ranges %}
                                        <option value="{{ length.pk }}">{{ length.range }}</option>
                                    {% endfor %}
                                </select>
                                , with hull type of
                                <select>
                                    <option value="*" selected>any</option>
                                    {% for hull in hull_types %}
                                        <option value="{{ hull.pk }}">{{ hull.type }}</option>
                                    {% endfor %}
                                </select>
                                with
                                <select>
                                    <option value="*" selected>any</option>
                                    {% for power in power_configs %}
                                        <option value="{{ power.pk }}">a {{ power.configuration }}</option>
                                    {% endfor %}
                                </select>
                                power
                                configuration and a top speed between
                                <select>
                                    <option value="*" selected>any MPH</option>
                                    {% for speed in speed_ranges %}
                                        <option value="{{ speed.pk }}">{{ speed.range }} MPH</option>
                                    {% endfor %}
                                </select>.
                                My budget is from <input type="text" value="{{ price.price__min|intword }}"
                                                         placeholder="{{ price.price__min|intword }}"
                                                         data-subline="Our current lowest price is: <em>{{ price__min|intword }}</em>"/>
                                to
                                <input
                                        type="text" value="{{ price.price__max|intword }}"
                                        placeholder="{{ price.price__min|intword }}"
                                        data-subline="Our current highest price is: <em>{{ price.price__min|intword }}</em>"/>
                                and hull only
                                availability <select>
                                <option value="False" selected>is not</option>
                                <option value="True">is</option>
                            </select> a concern.
                                <div class="container">
                                    <button type="submit"
                                            class="btn-a btn-a_size_large btn-a_color_theme">
                                        Show me the results!
                                    </button>
                                </div>
                            </form>

我知道这现在看起来一团糟,因为我从多个来源得到了不同的建议。我似乎无法使功能正确。

标签: djangodjango-formsdjango-filter

解决方案


不得不修改我的 IndexView 和我的表单,但它现在通过 get 请求传递值并将 kwargs 传递给下一个视图。这是当前代码:

表格.py

class ProductSearchForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(ProductSearchForm, self).__init__(*args, **kwargs)
        self.fields['length_range'].empty_label = "any size"
        self.fields['hull_type'].empty_label = "any type"
        self.fields['power'].empty_label = "any type"
        self.fields['speed'].empty_label = "any speed"
        self.fields['hull_only_available'].empty_label = None
        # self.fields['price'].widget.attrs['min'] = Product.price
        # self.fields['price'].widget.attrs['max'] = Product.price

    class Meta:
        model = Product
        fields = ('length_range', 'hull_type', 'price', 'power', 'speed', 'hull_only_available')

视图.py

class IndexView(FormView):
    template_name = 'index.html'
    form_class = ProductSearchForm
    success_url = "search/"

    def get_context_data(self, **kwargs):
        context = super(IndexView, self).get_context_data(**kwargs)
        context['length_ranges'] = LengthRange.objects.all().order_by('pk')
        context['hull_types'] = Hull.objects.all().order_by('pk')
        context['power_configs'] = PowerConfiguration.objects.all().order_by('pk')
        context['speed_ranges'] = SpeedRange.objects.all().order_by('pk')
        context['price'] = Product.objects.all().aggregate(Min('price'), Max('price'))
        return context

    def get_form_kwargs(self):
        kwargs = super(IndexView, self).get_form_kwargs()
        return kwargs

推荐阅读