相关文章推荐
兴奋的草稿本  ·  ASP.NET Core ...·  1 月前    · 
深情的伤疤  ·  Awk_百度百科·  4 周前    · 
聪明伶俐的煎鸡蛋  ·  Java UUID ...·  1 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm having a problem accessing a Django Form POST data.

I need to pass request.user to the form, so:

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()

and then call it using:

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():
else:
    form = TradeForForm(user=request.user)
variables = RequestContext(request, {
    'form': form,
    'item': item,
return render_to_response('trade_for.html', variables)

Now the problem is, when doing GET to access the empty form, it works just fine. But when I post it, I received an error:

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'

Now how can this be fixed? I assume it's because the user variable is not passed to the form when creating it using the request.POST data, but I want to be able to create the form with the user parameter and without it, both working.

you should probably pass the user to the form creator even with POST data so the choices can be validated properly, so

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

if you don't want this, you need to change user = kwargs.pop('user') to something like

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

pop will raise a KeyError unless it has a default value. So you just need to pass it a default value - probably None:

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

If you want the form to work without the user, change the constructor to:

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

But then you have to be able to deal with user being None.

The suggestion of user = kwargs.pop('user', None) is part of your missing code. A better approach would be to drop in your own arguments to avoid all the popping!

class TradeForForm(forms.Form):
    def __init__(self, user=None, request=None, *args, **kwargs):
        super(TradeForForm, self).__init__(*args, **kwargs)
        if user:
             ...code here...
                This isn't good because it changes the signature of forms. I would always expect to initialize a form with request.POST, request.FILES, but in this case, user must be the first arg.
– Yuji 'Tomita' Tomita
                Dec 2, 2011 at 19:16
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.