GrantU
GrantU

Reputation: 6555

Django int() argument must be a string or a number

I have a view which displays a form and saves the same form. When first showing the view I have no errors. However, when saving (POSTing) to the view I get the following error:

TypeError at /test6/settings/ int() argument must be a string or a number, not 'QueryDict'

View

@login_required
def keyword_settings(request, keyword):
    keyword = Keyword.objects.get(keyword=keyword, status="Active")

    # If we had a POST then get the request post values.
    if request.method == 'POST':
    # Populate the form with the instance.
        form = KeywordFrom(request.POST, instance=keyword)
        # Check we have valid data before saving trying to save.
        if form.is_valid():
            form.save()

    form = KeywordFrom(instance=keyword, user=request.user)
    context = {'form': form}
    return render_to_response('sms/keyword_settings.html', context, context_instance=RequestContext(request))

Form

class KeywordFrom(forms.ModelForm):

    def __init__(self, user=None, *args, **kwargs):
        """
        Init method.
        """
        super(KeywordFrom, self).__init__(*args, **kwargs)
        if user is not None:
            this_originator_name = Originator.objects.for_user(user)
            self.fields['sender_name'] = forms.ModelChoiceField(queryset=this_originator_name)

    class Meta:
        model = Keyword

I know the issue is with the sender_name but I have tried different things with no resolve.

Upvotes: 0

Views: 2007

Answers (1)

Daniel Roseman
Daniel Roseman

Reputation: 599490

Look at how you've overridden the __init__ method of your form:

def __init__(self, user=None, *args, **kwargs):

So the first explicit parameter (after the implicit self) is user.

Now look at how you're instantiating the form in the POST block:

form = KeywordFrom(request.POST, instance=keyword)

So the first parameter you're passing is the POST. But the form is expecting user in that position, and will put whatever you pass there into that variable.

You need to pass the user in when you instantiate on POST, which will fix the problem. But this indicates why it's a bad idea to mess around with the default signature of a class. You should really preserve the signature and take the user from kwargs:

def __init__(self, *args, **kwargs):
    user = kwargs.pop('user', None)
    super(KeywordFrom, self).__init__(*args, **kwargs)
    ...etc...

Upvotes: 7

Related Questions