带有ModelChoiceField的基于Django类的视图
我已经和Django一起工作了大约3个月了,我觉得自己已经好了一点,正在努力实现基于类的视图。从表面上看,它们看起来更干净、更容易理解,在某些情况下,它们的确如此。在其他国家,情况并非如此。我试图通过ModelChoiceField和表单使用一个简单的下拉视图。我可以让它使用基于函数的视图,如下所示,在my views.py文件中:带有ModelChoiceField的基于Django类的视图,django,python-3.x,django-forms,django-views,Django,Python 3.x,Django Forms,Django Views,我已经和Django一起工作了大约3个月了,我觉得自己已经好了一点,正在努力实现基于类的视图。从表面上看,它们看起来更干净、更容易理解,在某些情况下,它们的确如此。在其他国家,情况并非如此。我试图通过ModelChoiceField和表单使用一个简单的下拉视图。我可以让它使用基于函数的视图,如下所示,在my views.py文件中: def book_by_name(request): form = BookByName(request.POST or None) if requ
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”
我也尝试过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,我正在使用该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\u detail”相反,没有找到任何参数。为什么在那里使用
self.object
?您在原始视图中使用了form.cleaned_data
,这也是基于类的版本中应该使用的。请注意,表单被传递到form\u valid
注意,你也做了很多其他奇怪的事情。您的
get
方法是毫无意义的,您对initial
dict的定义也是如此;你应该同时删除它们。此外,FormView已经从View继承,您的声明中不需要显式包含View。您可以覆盖FormView中的form\u 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())
谢谢你花时间回答我的问题。正如我所写的,我在这方面是新手,因此我在论坛上提出了问题。你能详细解释一下语法吗?我根据你的评论更新了代码,这更接近你的建议吗?在玩了一些之后,我更新了视图以使用ListView,这就是我想要它做的,将书籍列表加载到我的modelchoicefield中。那很好。但是,当我尝试在modelchoicefield中选择一个条目时,它似乎无法显示单个记录。我快到了。。。