使用 formview 调用基于 class 的视图的 post 函数
Call post function of a class based view using formview
我是基于 django class 的视图的新手,可能我处理这个问题的方式有点天真,所以如果您能提出更好的方法,我将不胜感激。
所以我的问题是:
我的项目中存在三种类型的用户。 1. 学生,2. 老师,3. 家长。当用户以各自的形式请求设置页面时,我需要能够显示与每种类型的用户有关的不同用户设置。此外,我需要能够在用户提交表单时将数据保存到相应的表中。
我有一个基于 class 的视图 (UserSettingsView):
class UserSettingsView(LoginRequiredMixin, FormView):
success_url = '.'
template_name = 'accts/usersettings.html'
def get_initial(self):
if self.request.user.is_authenticated():
user_obj = get_user_model().objects.get(email=self.request.user.email)
if user_obj.profile.is_student:
return {
'first_name': user_obj.profile.first_name,
'last_name': user_obj.profile.last_name,
""" and other student field variables """
}
if user_obj.profile.is_teacher:
return {
""" Teacher field variables """
}
else:
return render_to_response('allauth/account/login.html')
def form_valid(self, form):
messages.add_message(self.request, messages.SUCCESS, 'Settings Saved!')
return super(UserSettingsView, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(UserSettingsView, self).get_context_data(**kwargs)
context['user'] = get_user_model().objects.get(email=self.request.user.email)
context['userprofile'] = UserProfile.objects.get(user_id=context['user'])
return context
def post(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
form.full_clean()
if form.is_valid():
user = request.user
user.profile.first_name = form.cleaned_data['first_name']
user.profile.last_name = form.cleaned_data['last_name']
user.profile.save()
if user.profile.is_student:
""" update student database """
user.save()
user.student.save()
if user.profile.is_teacher:
""" update teacher database """
user.save()
user.teacher.save()
return self.form_valid(form)
else:
return self.form_invalid(form)
使用 pick_settings 通用视图调用 Usersettings 视图的不同实例。
url(regex=r'^profilesettings/',view=pick_settings,name='profilesettings'),
这里是 pick_settings 视图:
def pick_settings(request):
if request.user.is_authenticated():
if request.method == 'GET':
if request.user.profile.is_student:
return UserSettingsView.as_view(form_class=StudentSettingsForm)(request)
if request.user.profile.is_teacher:
return UserSettingsView.as_view(form_class=TeacherSettingsForm)(request)
if request.user.profile.is_parent:
return UserSettingsView.as_view(form_class=ParentSettingsForm)(request)
else:
if request.method == 'POST':
"""
return ***<--- I need to know what to pass here to be able to call the appropriate post function of the UserSettingsView?---->"""***
else:
return HttpResponseRedirect('/accounts/login/')
我需要能够调用 UserSettingsView 的 post 函数。可能正在使用 get_context_data?但我不确定如何。
再一次,如果有人能提出更好的方法,那就太好了,因为我很确定这可能违反了 DRY 原则。不过,只要工作完成,我就不会太在意,因为我 运行 是最后期限。 :) 谢谢!
FormView
有一个方法 get_form_class()
。它是从 get()
和 post()
调用的,因此 self.request
已经设置(self.request.user
也会设置)。因此,
class UserSettingsView(LoginRequiredMixin, FormView):
[...]
def get_form_class(self):
# no need to check is_authenticated() as we have LoginRequiredMixin
if request.user.profile.is_student:
return StudentSettingsForm
elif user.profile.is_teacher:
return TeacherSettingsForm
elif user.profile.is_parent:
return ParentSettingsForm
当您为每种用户类型获得正确的表单时,这应该已经成功了。
如果你还需要渲染不同的模板,覆盖get_template_names()
:
def get_template_names(self):
if request.user.profile.is_student:
return ['myapp/settings/student.html']
elif user.profile.is_teacher:
return ['myapp/settings/teacher.html']
elif user.profile.is_parent:
return ['myapp/settings/parent.html']
DRY 可以在模板中结合通用模板片段使用适当的继承来实现。
以免我忘记(我已经忘记了):要摆脱视图的 post()
方法中的 if,只需重写我认为是 save()
的表单方法 ModelForm
s,无论如何。
我是基于 django class 的视图的新手,可能我处理这个问题的方式有点天真,所以如果您能提出更好的方法,我将不胜感激。
所以我的问题是:
我的项目中存在三种类型的用户。 1. 学生,2. 老师,3. 家长。当用户以各自的形式请求设置页面时,我需要能够显示与每种类型的用户有关的不同用户设置。此外,我需要能够在用户提交表单时将数据保存到相应的表中。
我有一个基于 class 的视图 (UserSettingsView):
class UserSettingsView(LoginRequiredMixin, FormView):
success_url = '.'
template_name = 'accts/usersettings.html'
def get_initial(self):
if self.request.user.is_authenticated():
user_obj = get_user_model().objects.get(email=self.request.user.email)
if user_obj.profile.is_student:
return {
'first_name': user_obj.profile.first_name,
'last_name': user_obj.profile.last_name,
""" and other student field variables """
}
if user_obj.profile.is_teacher:
return {
""" Teacher field variables """
}
else:
return render_to_response('allauth/account/login.html')
def form_valid(self, form):
messages.add_message(self.request, messages.SUCCESS, 'Settings Saved!')
return super(UserSettingsView, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(UserSettingsView, self).get_context_data(**kwargs)
context['user'] = get_user_model().objects.get(email=self.request.user.email)
context['userprofile'] = UserProfile.objects.get(user_id=context['user'])
return context
def post(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
form.full_clean()
if form.is_valid():
user = request.user
user.profile.first_name = form.cleaned_data['first_name']
user.profile.last_name = form.cleaned_data['last_name']
user.profile.save()
if user.profile.is_student:
""" update student database """
user.save()
user.student.save()
if user.profile.is_teacher:
""" update teacher database """
user.save()
user.teacher.save()
return self.form_valid(form)
else:
return self.form_invalid(form)
使用 pick_settings 通用视图调用 Usersettings 视图的不同实例。
url(regex=r'^profilesettings/',view=pick_settings,name='profilesettings'),
这里是 pick_settings 视图:
def pick_settings(request):
if request.user.is_authenticated():
if request.method == 'GET':
if request.user.profile.is_student:
return UserSettingsView.as_view(form_class=StudentSettingsForm)(request)
if request.user.profile.is_teacher:
return UserSettingsView.as_view(form_class=TeacherSettingsForm)(request)
if request.user.profile.is_parent:
return UserSettingsView.as_view(form_class=ParentSettingsForm)(request)
else:
if request.method == 'POST':
"""
return ***<--- I need to know what to pass here to be able to call the appropriate post function of the UserSettingsView?---->"""***
else:
return HttpResponseRedirect('/accounts/login/')
我需要能够调用 UserSettingsView 的 post 函数。可能正在使用 get_context_data?但我不确定如何。
再一次,如果有人能提出更好的方法,那就太好了,因为我很确定这可能违反了 DRY 原则。不过,只要工作完成,我就不会太在意,因为我 运行 是最后期限。 :) 谢谢!
FormView
有一个方法 get_form_class()
。它是从 get()
和 post()
调用的,因此 self.request
已经设置(self.request.user
也会设置)。因此,
class UserSettingsView(LoginRequiredMixin, FormView):
[...]
def get_form_class(self):
# no need to check is_authenticated() as we have LoginRequiredMixin
if request.user.profile.is_student:
return StudentSettingsForm
elif user.profile.is_teacher:
return TeacherSettingsForm
elif user.profile.is_parent:
return ParentSettingsForm
当您为每种用户类型获得正确的表单时,这应该已经成功了。
如果你还需要渲染不同的模板,覆盖get_template_names()
:
def get_template_names(self):
if request.user.profile.is_student:
return ['myapp/settings/student.html']
elif user.profile.is_teacher:
return ['myapp/settings/teacher.html']
elif user.profile.is_parent:
return ['myapp/settings/parent.html']
DRY 可以在模板中结合通用模板片段使用适当的继承来实现。
以免我忘记(我已经忘记了):要摆脱视图的 post()
方法中的 if,只需重写我认为是 save()
的表单方法 ModelForm
s,无论如何。