Django фильтрует данные в форме в другое представление - PullRequest
0 голосов
/ 21 марта 2019

Я не могу понять, что это правильно, и я просмотрел почти все подобные сообщения. И теперь я понятия не имею, что делает мой код. У меня есть индексная страница, которая имеет небольшую форму. Я просто хочу использовать эту форму для запроса моей базы данных и фильтрации результатов. Я использовал django-фильтры на другой странице, и она отлично работает, но я не могу передать данные из формы моей индексной страницы в следующее представление. Вот мой код:

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 голосов
/ 21 марта 2019

Пришлось изменить мой 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
0 голосов
/ 21 марта 2019

Проблема здесь, я думаю, заключается в том, что форма публикует свои данные в представлении search(), но это представление использует request.GET при передаче данных в ProductFilter, и request.GET будет пустым.

Pass request.POST вместо:

product_filter = ProductFilter(request.POST, queryset=product_list)
...