Django形成从视图传递的字段参数

时间:2014-11-16 23:05:46

标签: python django django-forms

我有一个简单的表格:

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无法识别。我错过了什么?

2 个答案:

答案 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参数时都会初始化它。似乎现在正在工作。