Django将表单中的数据过滤到另一个视图

时间:2019-03-20 22:15:10

标签: django django-forms django-filter

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

urls.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'),
]

views.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})

forms.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>

index.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>

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

2 个答案:

答案 0 :(得分:0)

我认为这里的问题是表单正在将其数据发布到#include <stdio.h> int main(void) { char s[] = "string"; return 0; } 视图,但是在将数据传输到search()时该视图正在使用request.GET和{{ 1}}将为空。

改为通过ProductFilter

request.GET

答案 1 :(得分:0)

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

form.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')

views.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