【发布时间】:2021-02-04 23:08:30
【问题描述】:
我有一个基于函数的视图,目前正在成功运行。但是,我想学习如何使用通用的 UpdateView 类创建此函数的等效基于类的视图版本——尽管我认为无论是什么解决方案,对于 CreateView 来说都是完全相同的。
我一般都知道如何创建和使用基于类的视图,但是我的基于函数的视图中有一行我无法在相应的 UpdateView 中工作——像往常一样使用通用编辑基于类的视图,目前尚不清楚我需要重写哪种方法来插入所需的功能。
可以说,我无法移植到 CBV 的特定任务是覆盖将用于显示特定字段的查询集的一行,该字段被定义为另一个模型的 ForeignKey在我的数据库中。
首先,基于工作函数的视图,在 CVB 版本中无法工作的特定代码位突出显示:
@login_required
def update_details(request, pk):
"""update details of an existing record"""
umd_object = UserMovieDetail.objects.select_related('movie').get(pk=pk)
movie = umd_object.movie
if umd_object.user != request.user:
raise Http404
if request.method != 'POST':
form = UserMovieDetailForm(instance=umd_object)
# this is the single line of code I can't get working in UpdateView version:
form.fields['user_guess'].queryset = User.objects.filter(related_game_rounds=movie.game_round)
else:
form = UserMovieDetailForm(instance=umd_object, data=request.POST)
if form.is_valid():
form.save()
return redirect(movie)
context = {'form': form, 'object': umd_object }
return render(request, 'movies/update_details.html', context)
我可以在 UpdateView 中成功地重新创建这个基于函数的视图的每个部分除了这行(为了清楚起见,从上面复制):
form.fields['user_guess'].queryset = User.objects.filter(related_game_rounds=movie.game_round)
这一行的作用:ForeignKey 的默认表单字段是 ModelChoiceField,默认显示相关模型的 所有 对象。我上面的代码覆盖了这种行为,并说:我只希望表单显示这组过滤的对象。只要我使用这个基于函数的视图,它就可以正常工作。
旁注: 我知道可以通过在我的 forms.py 文件中修改 ModelForm 本身来实现此结果。这个问题的目的是更好地理解如何使用内置的基于通用类的视图,使它们能够重新创建我已经可以使用基于函数的视图实现的功能。因此,请不要用“为什么不直接在表单本身中执行此操作”来回答我的问题——我已经知道这个选项,具体而言,这不是我要解决的问题。
现在是 UpdateView(我认为 CreateView 也是如此)。首先,它基本上看起来像这样:
class UpdateDetailsView(LoginRequiredMixin, UpdateView):
model = UserMovieDetail
template_name = 'movies/update_details.html'
form_class = UserMovieDetailForm
login_url = 'login' # used by LoginRequiredMixin
# what method do I override here, to include that specific line of code, which needs
# to occur in the GET portion of the view?
def get_success_url(self):
return reverse('movies:movie', kwargs={'pk': self.object.movie.pk, 'slug': self.object.movie.slug })
以上是我基于函数的视图的重新创建,复制了所有行为除了过滤特定字段的 ModelChoiceField 显示在表单中的结果的重要行。 p>
如何让该行代码在此 UpdateView 中运行?我在 classy 基于类的视图 网站上查看了 UpdateView 内置的方法,然后尝试(通过纯粹的猜测)覆盖 get_form_class方法,但我没有用,我一开始基本上是在黑暗中拍摄。
请注意,由于我要重新创建的功能是关于在表单的 ModelChoiceField 中显示项目,因此所需的行为适用于视图的 GET 部分,而不是 POST。所以我需要能够在第一次呈现表单之前覆盖表单字段,就像我在基于函数的视图中所做的那样。在 UpdateView 中的何处以及如何执行此操作?
【问题讨论】:
标签: django django-class-based-views modelform