DjangoGuy
DjangoGuy

Reputation: 103

filter manytomanyfield form 'str' object has no attribute 'get'

I have theses classes in my models.py

class Parent(models.Model):
    title = models.CharField()

class Child(models.Model): 
    title = models.CharField()
    parent = models.ForeignKey(Parent)

class Address(models.Model)
    title = models.CharField()
    parent = models.ForeignKey(Parent)
    child = models.ManyToManyField(Child)

Because I wanted "child" field in "Address" model only displays "child" objects that are related to "parent" I wrote this code to my forms.py

class AddressForm(forms.ModelForm):

    class Meta:
        model = Address
        fields = ('title', 'parent', 'child')

    def __init__(self, parent_id, *args, **kwargs):
        super(AddressForm, self).__init__(*args, **kwargs)
        self.fields['child'].queryset = Child.objects.filter(parent__id=parent_id)

views.py

def address(request, parent_id):
    parent = get_object_or_404(Parent, id=parent_id)
    if request.method == 'POST':
        form = AddressForm(request.POST, parent_id)
        if form.is_valid():
            address = form.save(commit=False)
            address.parent = parent
            address.save()
            return redirect('app:address_added')
    else:
        form = AddressForm(parent_id)
    template = "add_address.html"
    context = {'form': form}
    return render(request, template, context)

The result : the child field displays only the child objects related to parent requested. which what I want.

The problem : when I submit I get this error :

AttributeError at /manage/add_address/ 'str' object has no attribute 'get'

Traceback:

File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/core/handlers/exception.py" in inner 39. response = get_response(request)

File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response 187. response = self.process_exception_by_middleware(e, request)

File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response 185. response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/Users/Developer/Desktop/Projects/******/***/views.py" in add_address 167. if form.is_valid():

File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/forms/forms.py" in is_valid 169. return self.is_bound and not self.errors

File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/forms/forms.py" in errors 161. self.full_clean()

File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/forms/forms.py" in full_clean 370. self._clean_fields()

File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/forms/forms.py" in _clean_fields 382. value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))

File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/forms/widgets.py" in value_from_datadict 427. upload = super(ClearableFileInput, self).value_from_datadict(data, files, name)

File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/forms/widgets.py" in value_from_datadict 354. return files.get(name)

Exception Type: AttributeError at /manage/add_address/ Exception Value: 'str' object has no attribute 'get'

Help please?

Upvotes: 0

Views: 1739

Answers (1)

Daniel Roseman
Daniel Roseman

Reputation: 599778

You've made parent_id the first positional argument to the form, so you should pass it as such in the POST block:

form = AddressForm(parent_id, request.POST)

Note that it is better not to change the signature of the form at all, but use kwargs:

def __init__(self, *args, **kwargs):
    parent_id = kwargs.pop('parent_id', None)
    super(AddressForm, self).__init__(*args, **kwargs)

and do:

form = AddressForm(request.POST, parent_id=parent_id)

in the POST block and

form = AddressForm(parent_id=parent_id)

in the else.

Upvotes: 1

Related Questions