基于类的FormView

时间:2017-11-23 20:06:46

标签: django python-3.x django-forms django-templates django-views

我已经研究了这个问题几天了,似乎无法找到我正在寻找的东西。我在StackOverflow以及Google上搜索了ModelChoiceField以及ChoiceField,我的问题有很多变化,但没有确切的。简而言之,我尝试使用基于类的FormView,然后捕获用户选择并将其传递给基于类的ListView。这是我的代码。

Forms.Py

class BookByStatus(forms.Form):

   dropdown = forms.ChoiceField(choices=[],required=False)

   def __init__(self, user, *args, **kwargs):
        super(BookByStatus, self).__init__(*args, **kwargs)
        self.fields['dropdown'].widget.attrs['class'] = 'choices1'
        self.fields['dropdown'].empty_label = ''
        self.fields['dropdown'].choices = 
        Book.objects.values_list("author","author").distinct("Publisher")

上面的代码工作正常,并向我显示我在我的视图中寻找的输出。没有问题....然后我有我的FormView ...

class BookByStatusView(LoginRequiredMixin,FormView):
    model = Book
    form_class = BookByStatus
    template_name = 'xyz123/publisher.html'
    success_url = reverse_lazy('Book:book_by_list',kwargs=
                               {'dropdown':'dropdown'})

    def get_form_kwargs(self):
        kwargs = super(BookByStatusView, self).get_form_kwargs()
        kwargs['user'] = self.request.user        
        return kwargs

    def form_valid(self, form):
        self.request.POST['dropdown']
        BookByStatusView = form.cleaned_data['dropdown']
        return super(BookByStatusView, self).form_valid(form)

上面的代码运行正常,但是我带到下面的ListView,我似乎无法将下拉值传递给....我已经尝试了几次不同的get_form_kwargs迭代以及更改了我的表单到ModelChoiceField,但仍然无法理解如何根据用户的输入获取查询集...

最后是ListView ......

class BookByStatusListView(LoginRequiredMixin,ListView):
    model = Book
    form_class = BookByStatus
    context_object_name = 'book_list'
    template_name = 'xyz123/book_by_status_list.html'
    paginate_by = 15

    def get_queryset(self, *kwargs):
        form = self.form_class(self.request.GET)
        dropdown = self.kwargs.get('dropdown', None)
        if form.is_valid():
            return Book.objects.filter(dropdown__icontains=form.
            cleaned_data['dropdown'])
        return Book.objects.all()

我尝试从FormView获取下拉输入,然后使用两个单独的视图将其传递给列表视图。我需要将值从FormView传递给ListView。我清楚如何在ChoiceField中的FormView中获取数据,以及如何显示ListView,但我似乎无法弄清楚如何将下拉数据从FormView传递到ListView。我可以使ListView工作,但只能使用完整的查询集,而不是过滤的。

这是书模型......

class Book(models.Model):
    Author CHOICES = (
        ("New","New"),
        ("Old","Old"),
    )

    Author = models.CharField(choices=Author_CHOICES,max_length=10)

这是网址...

url(r'^book_by_list/(?
P<dropdown>\w+)/$',views.BookByStatusListView.as_view(), 
name='book_by_list'),

提前感谢任何建议!

更新方法...使用request.session。无论我尝试了多少get_context_data或get_form_kwargs组合,我之前的方法都不允许我将值从一个视图传递到另一个视图。根据我收到的意见,我开始探索request.session方法,并且我进一步深入了解。最后一篇文章仍然存在,在我的LISTVIEW中获取request.session值,因此我可以相应地过滤我的查询集。

class BookByStatusView(LoginRequiredMixin,FormView):

    model = Book
    form_class = BookByStatus
    template_name = 'xyz123/publisher.html'
    success_url = reverse_lazy('Book:book_by_list') 

    def form_valid(self, form):
        self.request.session['dropdown'] = form.cleaned_data['dropdown']
        return super(BookByStatusView, self).form_valid(form)

    def get_form_kwargs(self):
        kwargs = super(BookByStatusView, self).get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

在我的html模板中,我将request.session值用作...

{{ request.session.dropdown }}

我将网址还原为..

url(r'^book_by_list/$,views.BookByStatusListView.as_view(), 
name='book_by_list'),

最后剩下的部分是弄清楚如何利用LISTVIEW这种方法。

我目前的Listview:

class BookByStatusListView(LoginRequiredMixin,ListView):
    model = Book
    form_class = BookByStatus
    context_object_name = 'book_list'
    template_name = 'xyz123/book_by_status_list.html'
    paginate_by = 15

def get_queryset(self):
    queryset = Book.objects.none()
    dropdown = self.request.session.get('dropdown')
    if dropdown == 'New':
        queryset = Book.objects.all()
    elif dropdown == 'Old':
        queryset = Book.objects.none()
    return queryset

我似乎无法弄清楚如何将下拉值正确传递给ListView,以便正确显示查询集。根据我的测试,我似乎没有在get_queryset函数中正确捕获下拉列表。有任何想法吗?

我明白了。我用正确的语法更新了get_queryset。感谢所有的帮助,使我朝着正确的方向努力。最后一个问题..这是将值从一个视图传递到另一个视图的最佳方法吗?有一个更好的方法吗?这种方法有什么问题吗?

1 个答案:

答案 0 :(得分:1)

这不起作用,因为重定向会创建新的请求/响应,并且之前的数据会丢失。如果我理解了您想要的内容,其中一个选项是将下拉值保存到BookByStatusView中的会话,然后在BookByStatusListView中检索。

您使用以下内容保存到会话:

request.session['dropdown_value'] = form.cleaned_data['dropdown']

并检索:

dropdown_value = request.GET.get('dropdown_value')

以下是Django文档的How to use session部分。

编辑:您也可以将值作为url参数传递,如下所示:

author = 'michael cricthon'
title = 'kongo'
year = [1999, 2000, 2001]
type = ['electronic', 'print', 'hardcover', 'softcover']

params = '?author={}&title={}&&year={}&type={}'.format(
            urllib.parse.quote_plus(author), 
            urllib.parse.quote_plus(title),
            ','.join(year),
            ','.join(type))

return HttpResponseRedirect(reverse('search') + params)

链接看起来像这样:

../search/?author=michael+crichton&title=kongo&year=1999,2000,2001&type=electronic,print,hardcover,softcover

您可以使用

获取参数
author = request.GET.get('author')
title = request.GET.get('title')
... etc.