使用ModelChoiceField的基于Django类的视图

时间:2017-09-30 21:05:10

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

我已经和Django一起工作了大约3个月了,感觉自己变得更好了,一路走向基于课堂的观点。从表面上看,它们看起来更干净,更容易理解,在某些情况下它们也是如此。在其他人,而不是。我试图通过ModelChoiceField和一个表单使用一个简单的下拉视图。我可以使用基于函数的视图,如下面的views.py文件中所示:

def book_by_name(request):
    form = BookByName(request.POST or None)
    if request.method == 'POST':
        if form.is_valid():
            book_byname = form.cleaned_data['dropdown']
            return HttpResponseRedirect(book_byname.get_absolute_url1())
    return render(request,'library/book_list.html',{'form':form})

这是我在forms.py中的表单:

class BookByName(forms.Form):

    dropdown = forms.ModelChoiceField(queryset=Book.objects.none())

    def __init__(self, *args, **kwargs):
        super(BookByName, self).__init__(*args, **kwargs)
        self.fields['dropdown'].widget.attrs['class'] = 'choices1'
        self.fields['dropdown'].empty_label = ''
        self.fields['dropdown'].queryset = Book.objects.order_by('publisher')

此代码有效。当我试图转换为基于类的视图时,那就是麻烦开始的时候。我试图在views.py中执行类似的操作:

class BookByNameView(FormView, View):
    form_class = BookByName
    initial = { 'Book' : Book }
    template_name = 'library/book_list.html'

    def get(self, request, *args, **kwargs):
        form = self.form_class(initial=self.initial)
        return render(request, self.template_name, {'form': form})

    def get_success_url(self, *args):
        return reverse_lazy('library:book_detail', args = (self.object.id,))

使用相同表单时,我收到属性错误

  

' BookByNameView' object没有属性' object'。

我也尝试过ListView,并在此过程中收到了其他一些错误。 get_success_url还需要接收主键,我也无法弄清楚如何传入。再次,我是一个3个月的Django新手,所以请保持温柔,并提前感谢您的想法和建议!我觉得我在球场上......只是找不到座位!如果有更清洁/更好的方法,我会非常愿意以不同的方式做到这一点!

根据最新的反馈,基于类的视图应该看起来像:

class BookNameView(FormView):
    form_class = BookName
    template_name = 'library/book_list.html'

    def get_success_url(self, *args):
        return reverse_lazy('library:book_detail')

这是对的吗?我运行了一个测试版本,并回答你的问题,为什么我一直在使用self.object.id,我试图从我正在使用的modelchoicefield获取pk来返回我想要的视图。这可能是我有点迷失的地方。我正在尝试从modelchoicefield下拉列表中获取详细信息视图,并返回所选的书籍。但是,我似乎无法成功地将pk传递给此视图。

我将代码更新为...

class BookByNameView(FormView, ListView):
    model = Book
    form_class = BookByName
    template_name = 'library/book_list.html'

    def get_success_url(self, *args):
        return reverse_lazy('library:book_detail')

但是现在它说错误......反向' book_detail'没有找到参数。

2 个答案:

答案 0 :(得分:1)

为什么你在那里使用self.object?您在原始视图中使用了form.cleaned_data,这也是您应该在基于类的版本中使用的内容。请注意,表单将传递给form_valid

请注意,您还做了很多其他奇怪的事情。您的get方法毫无意义,因为您对initial字典的定义也是如此;你应该删除它们。此外,FormView已经从View继承,因此无需在声明中明确显示View。

答案 1 :(得分:0)

您可以在FormView中覆盖form_valid()函数以实现您想要的效果。如果表单有效,则将其传递给form_valid()函数。

试试这个:

class BookByNameView(FormView):
       model = Book
       form_class = BookByName
       template_name = 'library/book_list.html'

       def form_valid(self, form):
            bookbyname = form.cleaned_data['dropdown']
            return HttpResponseRedirect(bookbyname.get_absolute_url())