2

I am fairly new with django and I am having a problem and would like to request some assistance.

I am getting an error with passing my custom param to my form that says

KeyError at /someurl
'my_arg'

    Request Method: GET
    Request URL:    http://localhost:8000/
    Django Version: 1.8.2
    Exception Type: KeyError
    Exception Value: 'my_arg'
    Exception Location: ..../forms.py in __init__, line 108(points at 'my_arg = kwargs.pop('my_arg')' line)
    Python Executable:  C:\Python27\python.exe
    Python Version: 2.7.10
    Python Path:    
    ['C:\\Users\\lolwat\\Desktop\\ITSWEBSITE',
     'C:\\Windows\\system32\\python27.zip',
     'C:\\Python27\\DLLs',
     'C:\\Python27\\lib',
     'C:\\Python27\\lib\\plat-win',
     'C:\\Python27\\lib\\lib-tk',
     'C:\\Python27',
     'C:\\Python27\\lib\\site-packages']

It also say this at the error page:

Error during template rendering
    ...
    {% for field in form %}
    ...

This is my form:

class BaseFormSet(BaseInlineFormSet):
    def __init__(self, *args, **kwargs):
    self.my_arg = kwargs.pop("my_arg")
    super(BaseFormSet, self).__init__(*args, **kwargs)

class SomeForm(ModelForm):
    ...
    def __init__(self, *args, **kwargs):
        my_arg = kwargs.pop('my_arg')
        super(SomeForm, self).__init__(*args, **kwargs)

And my views:

myformset = inlineformset_factory(modelA, modelB, formset = BaseFormSet, form=SomeForm, extra=1, can_delete=True)

def someview(request, obj_id):
    var1 = get_object_or_404(SomeModel, id = obj_id)
    somevalue = var1.ModelFieldValue
    form = myformset (request.POST, my_arg=somevalue)
    if request.method == 'POST':
        ...
    else:
        form = myformset(instance = myinstance, my_arg=somevalue)

     return render(....)

What I am doing wrong or am I doing it right? Many thanks.

UPDATE

I tried using myformset.form = staticmethod(curry(SomeForm, my_arg=somevalue))

And my views look like this:

from django.utils.functional import curry

myformset = inlineformset_factory(modelA, modelB, formset = BaseFormSet, form=SomeForm, extra=1, can_delete=True)

def someview(request, obj_id):
    var1 = get_object_or_404(SomeModel, id = obj_id)
    somevalue = var1.ModelFieldValue
    myformset.form = staticmethod(curry(SomeForm, my_arg=somevalue))
    form = myformset (request.POST, my_arg=somevalue)
    if request.method == 'POST':
        ...
    else:
        form = myformset(instance = myinstance, my_arg=somevalue)

     return render(....)

And It's working, I am using the my_arg to filter the SomeForm's ModelChoiceField queryset via __init__ and my form looks like this:

class SomeForm(ModelForm):
   MyField = ModelChoiceField(queryset=SomeModel.objects.none())
    def __init__(self, *args, **kwargs):
        my_arg = kwargs.pop('my_arg', None)
        super(SomeForm, self).__init__(*args, **kwargs)
        self.fields['MyField'].queryset = SomeModel.objects.filter(fkey = my_arg)

And upon save I get <DjangoObject> is not JSON serializable error

1 Answer 1

2

You get this error because your inner form SomeForm does not receive my_arg as a parameter in kwargs. And because you use kwargs.pop('my_arg') without a default value -> you get a KeyError. If you use .pop with a default value provided (kwargs.pop('my_arg', None)) you wont get a KeyError.

If you really need to pass my_arg to your inner SomeForm take a look at this questions: here, here and here

UPDATE:

As far as I can see, you need my_arg to filter queryset of a field. Well you don't need to this at inner_form.__init__, but after constructing all forms inside your formset.__init__ method.

Something like this:

class BaseFormSet(BaseInlineFormSet):
    def __init__(self, *args, **kwargs):
        my_arg = kwargs.pop("my_arg")
        super(BaseFormSet, self).__init__(*args, **kwargs)
        for form in self.forms:
            form.fields['my_field'].queryset = SomeModel.objects.filter(fkey = my_arg)
Sign up to request clarification or add additional context in comments.

5 Comments

Many thanks for the answer, I tried using myformset.form = staticmethod(curry(SomeForm, my_arg=somevalue)) and now I am getting an error: <DjangoObject> is not JSON serializable
Just by the error I don't think I can help you. I personally never needed to send additional parameter to an inner form, so I'm not quite sure whats the best approach to do it. When I have time I will try it myself and post you and update, until then - keep reading :)
I'll post another question because I tested it and this is another matter entirely, good read tho, thanks for pointing me in the right direction
I'm getting a [u'ManagementForm data is missing or has been tampered with'] error with that
Yes, it's in my template, what causes it I think is the for loop in the BaseFormSet as it is Tampered with, anyway what I did works though

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.