Search code examples
pythondjango

Django FilteredSelectMultiple: 'TypeError while rendering: unpack non-sequence'


I'm trying to replace the default ManyToManyField widget in the Admin to use a FilteredSelectMultiple, and I'm having some issues. My error is Caught TypeError while rendering: unpack non-sequence

Here is my model

class Car(models.Model):
    parts = models.ManyToManyField('Part')

class Part(models.Model):
    name = models.CharField(max_length=64)

And this is my ModelAdmin

class CarAdmin(admin.ModelAdmin):
    form = myforms.CustomCarForm

And this is CustomCarForm

 class CustomCarForm(forms.ModelForm):
     def __init__(self, *args, **kwargs):
         super(CustomCarForm, self).__init__(*args, **kwargs)
         parts = tuple(Part.objects.all())
         self.fields['parts'].widget = admin.widgets.FilteredSelectMultiple(
             'Parts', False, choices=parts
         )

I receive this error when I try to view the Admin form

Request Method:     GET
Request URL:        http://127.0.0.1:8000/admin/foo/car/1/
Django Version:     1.2.5
Exception Type:     TemplateSyntaxError
Exception Value:    Caught TypeError while rendering: unpack non-sequence
Exception Location: /usr/lib/python2.4/site-packages/Django-1.2.5-py2.4.egg/django/forms/widgets.py in render_options, line 464
Python Executable:  /usr/bin/python
Python Version:     2.4.3

This error occurs if I use any of these to set parts

parts = Part.objects.all()
parts = list(Part.objects.all())
parts = tuple(Part.objects.all())

If I do this

parts = Part.objects.value_list('name')

I get Caught ValueError while rendering: need more than 1 value to unpack

Edit: If I take out choices=parts it renders fine, but the selection boxes are blank, and I need to have something in them.


Solution

  •         for option_value, option_label in chain(self.choices, choices):
    

    Apparently, choices is a list of tuples, first value being option_value and the second is option_label.

    I'm not sure what the first needs to be, but I'm guessing pk.

    Try:

    parts = [(x.pk, x.name) for x in Part.objects.all()]