gpt4 book ai didi

python - 在 Django 中将请求对象从 View 传递到表单

转载 作者:行者123 更新时间:2023-12-01 04:50:05 25 4
gpt4 key购买 nike

我正在尝试创建一个帐户编辑页面,该页面在视觉上包含单个表单(即单个提交按钮),但字段是两个(或更多)不同模型的一部分。我已经从几个 SO 答案中拼凑出一个解决方案,并且表单在 GET 请求上加载良好,但我现在想根据正在访问的 url 有条件地隐藏/显示服务条款复选框字段。特别是在注册时,应显示 TOS,而不应显示在帐户编辑页面上。简化的代码如下所示:

# views.py

class _RequestPassingFormView(FormView):
http_method_names = ['get', 'post', 'head', 'options', 'trace']

def get(self, request, *args, **kwargs):
# Pass request to get_form_class and get_form for per-request
# form control.
form_class = self.get_form_class(request)
form = self.get_form(form_class)
return self.render_to_response(self.get_context_data(form=form))

def post(self, request, *args, **kwargs):
# Pass request to get_form_class and get_form for per-request
# form control.
form_class = self.get_form_class(request)
form = self.get_form(form_class)
if form.is_valid():
# Pass request to form_valid.
return self.form_valid(request, form)
else:
return self.form_invalid(form)

def get_form_class(self, request=None):
return super(_RequestPassingFormView, self).get_form_class()

def get_form_kwargs(self, request=None, form_class=None):
return super(_RequestPassingFormView, self).get_form_kwargs()

def get_initial(self, request=None):
return super(_RequestPassingFormView, self).get_initial()

def get_success_url(self, request=None, user=None):
# We need to be able to use the request and the new user when
# constructing success_url.
return super(_RequestPassingFormView, self).get_success_url()

def form_valid(self, form, request=None):
return super(_RequestPassingFormView, self).form_valid(form)

def form_invalid(self, form, request=None):
return super(_RequestPassingFormView, self).form_invalid(form)


class AccountEditView(_RequestPassingFormView):
form_class = AccountEditForm
template_name = 'account_edit.html'

def form_valid(self, request, form):
success_url = self.get_success_url(request, new_user)

try:
to, args, kwargs = success_url
return redirect(to, *args, **kwargs)
except ValueError:
return redirect(success_url)

def get_success_url(selfself,request, user):
return '/account'




#forms.py

class CombinedFormBase(forms.Form):
form_classes = []

def __init__(self, *args, **kwargs):
super(CombinedFormBase, self).__init__(*args, **kwargs)
for f in self.form_classes:
name = f.__name__.lower()
setattr(self, name, f(*args, **kwargs))
form = getattr(self, name)
self.fields.update(form.fields)
self.initial.update(form.initial)

def is_valid(self):
isValid = True
for f in self.form_classes:
name = f.__name__.lower()
form = getattr(self, name)
if not form.is_valid():
isValid = False
# is_valid will trigger clean method
# so it should be called after all other forms is_valid are called
# otherwise clean_data will be empty
if not super(CombinedFormBase, self).is_valid() :
isValid = False
for f in self.form_classes:
name = f.__name__.lower()
form = getattr(self, name)
self.errors.update(form.errors)
return isValid

def clean(self):
cleaned_data = super(CombinedFormBase, self).clean()
for f in self.form_classes:
name = f.__name__.lower()
form = getattr(self, name)
cleaned_data.update(form.cleaned_data)
return cleaned_data


class RegistrationForm(forms.Form):
required_css_class = 'required'
email = forms.EmailField(label=_('E-mail'))
password1 = forms.CharField(widget=forms.PasswordInput,
label=_('Password'))
password2 = forms.CharField(widget=forms.PasswordInput,
label=_('Password (again)'))

"""
Conditionlly display TOS checkbox based on context

"""
def __init__(self, *args, **kwargs):
"""
add in a field for terms of service here if viewing
the registration form
"""

super(RegistrationForm, self).__init__(*args, **kwargs)

class AccountProfileForm(forms.Form):
required_css_class = 'required'
company = forms.CharField(label=('Company Name'))


class AccountEditForm(CombinedFormBase):
form_classes = [RegistrationForm, AccountProfileForm]

这是我的第一个 django 项目,所以这也可能是一个完全错误的方向。如果是这样,我们将不胜感激提供更简单的解决方案的提示。

最佳答案

由于您使用的是基于类的 View ,我认为您可以尝试这样:

查看:

class _RequestPassingFormView(FormView):
http_method_names = ['get', 'post', 'head', 'options', 'trace']

def get(self, request, *args, **kwargs):
form_class = self.get_form_class()
self.object = None
form = form_class(request_data=request)
return self.render_to_response(self.get_context_data(form=form))

或者像这样:

class _RequestPassingFormView(FormView):
http_method_names = ['get', 'post', 'head', 'options', 'trace']

#No need to override the get method in this view.


def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs.update(request_data=self.request)
return kwargs

形式是这样的:

class RegistrationForm(forms.Form):

#form fields

def __init__(self, *args, request_data=None, **kwargs):
super().__init__(*args, **kwargs)
print(request_data)
# do other operations

关于python - 在 Django 中将请求对象从 View 传递到表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28653699/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com