我有一个简单的表格:
class MyForm(forms.Form):
my_field = forms.IntegerField(min_value=0)
我的应用中的每个用户都有变量存储在名为' my_amount'的会话中。我想从我的基于类的FormView传递此变量(或会话或请求)。
我发现我应该这样做:
class MyFormView(FormView):
form_class = MyForm
def get_form_kwargs(self, **kwargs):
kwargs = super(MyFormView, self).get_context_data(**kwargs)
kwargs['my_amount'] = self.request.session.get('my_amount')
return kwargs
我用这种方式修改了表单:
class MyForm(forms.Form):
def __init__(self, **kwargs):
self.my_amount = kwargs.pop('my_amount')
return super(MyForm, self).__init__(self, **kwargs)
my_field = forms.IntegerField(min_value=0, max_value=self.my_amount)
但Django显示错误" self"在max_value = self.my_amount无法识别。我错过了什么?
答案 0 :(得分:0)
错误发生在您发布的最后一行代码中:
my_field = forms.IntegerField(min_value=0, max_value=self.my_amount)
Python(不是django)无法解析,因为该行的范围内没有“self”。你在那里定义一个类范围标识符。
但是,这并没有回答如何使代码实现其目的的更大问题。我不遵循你想要做的事情,将变量保持在会话中然后是一个表单,但是一眼就看出代码对于这样一个简单的意图看起来很复杂。也许更多地阐明目标,可能在一个单独的问题中提出是否还有问题?
修改
根据您的评论,我做了一个小型演示。 HTML:
<html>
<body>
<p>Your balance is <strong>{{balance}}</strong>.</p>
<form method='POST'>
<input name='key' type='text' placeholder="Enter 'good', 'great' or 'bad' for a result">
<input name='submit' type='submit' value="Go">
</form>
<body>
</html>
观点:
from django.shortcuts import render, redirect
def index(request):
# ensure initial balance
balance = request.session.get('balance', 0)
if request.method == 'POST':
key = request.POST.get('key')
if key == 'good':
balance += 10
elif key == 'great':
balance += 50
elif key == 'bad':
balance -= 5
# Persist the balance in the session
request.session['balance']=balance
# You could omit these two lines but by redirecting back to the 'GET'
# form you don't have to worry about "resubmitting the form" warnings.
if request.method == 'POST':
return redirect(request.path)
return render(request, 'nov17/index.html', dict(balance=balance))
首次加载页面时,它会显示:
Your balance is 0.
[text input] [Go]
如果您在输入中键入“good”并按下按钮,则会添加10个点。输入'great'并添加50分等等。
当然,这是一个玩具,但它证明基于动作修改会话变量非常简单。
我没有按照“我希望用户能够在my_field中发布不超过会话中存储的my_amount的号码”的部分进行操作,但我认为这是一个单独的问题。
答案 1 :(得分:0)
我无意中找到了问题的答案。正如Andrew E.在评论中所述,表单字段是在第一个过程中设置的,而不是每次调用表单时都是如此。但每次调用表单类 init (self)方法。所以我可以用这种方式创建它:
class MyForm(forms.Form):
my_field = forms.IntegerField(min_value=0)
def __init__(self, **kwargs):
my_amount = kwargs.pop('my_amount')
super(MyForm, self).__init__(self, **kwargs)
self.fields['my_field'].max_value = my_amount
现在my_field在start时设置,但每次从视图传递max_value参数时都会初始化它。似乎现在正在工作。