2011-12-02 83 views
0

我在访问Django表单POST数据时遇到问题。request.user in Django表格

我需要传递request.user到形式,所以:

class TradeForForm(forms.Form): 
def __init__(self, *args, **kwargs): 
    user = kwargs.pop('user') 
    else: 
     request = kwargs.pop('request') 
    super(TradeForForm, self).__init__(*args, **kwargs) 

    #Obtain items for user 
    if user: 
     print user 
     items = Item.objects.filter(user=user) 
     choices = [] 
     for i in range(len(items)): 
      choices.append([i,items[i].name]) 

     self.fields['item_to_be_traded_for'].choices = choices 

trade_type = forms.ChoiceField(
    widget=RadioSelect(), 
    choices = [ 
     ['0','Item'], 
     ['1','Money offer'], 
    ] 
) 

item_to_be_traded_for = forms.ChoiceField() 

,然后使用调用它:

def trade_for(request, item_id): 
item = Item.objects.get(id=item_id) 

if request.method == 'POST': 
    form = TradeForForm(request.POST) 

    if form.is_valid(): 
     pass 
else: 
    form = TradeForForm(user=request.user) 

variables = RequestContext(request, { 
    'form': form, 
    'item': item, 
}) 

return render_to_response('trade_for.html', variables) 

现在的问题是,在执行GET时访问空表单,它工作得很好。但是当我发布它时,我收到一个错误:

KeyError at /trade_for/1/ 
'user' 
Request Method: POST 
Request URL: http://localhost:8000/trade_for/1/ 
Django Version: 1.3.1 
Exception Type: KeyError 
Exception Value:  
'user' 

现在该如何解决?我认为这是因为在使用request.POST数据创建它时,用户变量没有传递到窗体,但我希望能够使用用户参数创建窗体并且不用它,两者都可以工作。

回答

5

你应该通过用户表单作者甚至POST数据,所以选择可以正确验证,所以

TradeForForm(request.POST, user=request.user) 

,如果你不希望这样,您需要更改user = kwargs.pop('user')喜欢的东西

user = kwargs.pop('user', None) 
# if kwargs has no key 'user', user is assigned None 
# make sure your code handles this case gracefully 
+0

完美的工作。谢谢! –

+0

这个解释更加完整:http://mikethecoder.tumblr.com/post/5865162520/django-form-request-user – jumpfightgo

1

如果你想要的形式,而用户的工作,改变构造函数:

user = kwargs.pop('user', None) 

但你必须能够应付userNone

+0

是的,就是这样。谢谢! –

2

pop将引发KeyError,除非它具有默认值。所以,你只需要通过它的默认值 - 大概None

user = kwargs.pop('user', None) 
+0

是的,就是这样。谢谢! –

+0

不要忘记接受答案... – intargc

0

的的建议是你的代码丢失的一部分。一个更好的方法是放弃你自己的论点,以避免所有的弹出!

class TradeForForm(forms.Form): 
    def __init__(self, user=None, request=None, *args, **kwargs): 
     super(TradeForForm, self).__init__(*args, **kwargs) 

     if user: 
      ...code here... 
+0

这不好,因为它改变了表单的签名。我总是希望用request.POST,request.FILES来初始化一个表单,但在这种情况下,用户必须是第一个参数。 –

+0

是的,这是一个python 3主题。不适用于django。 – koblas