views:

26

answers:

1

Is it possible for an inlineformset_factory to take in a ModelForm as well as a model. When I try to run this I get an error message 'NoneType' object is not iterable.

Please help, I've spent an entire day trying to figure this out. Thanks.

Code:

Model.py

class FilterForm(ModelForm):
firstFilter = forms.BooleanField(label='First Filter', initial=False, required=False)
class Meta:
    model = Filter
    exclude = ('order')


class Controller(models.Model):
protocol = models.CharField('Protocol',max_length=64, choices=PROTOCOLS, default='http')
server = models.CharField('Server', max_length=64, choices=SERVERS, default='127.0.0.1')
name = models.CharField('Name', max_length=64)

def __unicode__(self):
    return self.protocol + '://' + self.server + '/' + self.name

view.py

def controller_details(request, object_id):
controller = Controller.objects.get(pk=object_id)
controllerURI = controller.protocol + '://' + controller.server + '/' + controller.name
FilterFormSet = inlineformset_factory(Controller, FilterForm, extra=5)

if request.method == 'POST':
    formset  = FilterFormSet(request.POST, request.FILES, instance=controller)

    if formset.is_valid():
        filters = []

        # Save all the filters into a list
        forms = formset.cleaned_data
        for form in forms:
            if form:        
                protocol = form['protocol']
                server = form['server']
                name = form['name']
                targetURI = form['targetURI']
                filterType = form['filterType']
                firstFilter = form['firstFilter']

                if firstFilter == True:
                    aFilter = Filter(controller=controller, protocol=protocol, server=server, name=name, targetURI=targetURI, filterType=filterType, order=0)
                else:
                    aFilter = Filter(controller=controller, protocol=protocol, server=server, name=name, targetURI=targetURI, filterType=filterType, order=-1)

                filters.append(aFilter)

        # Find the first filter in the list of filters
        for index, aFilter in enumerate(filters):
            if aFilter.order == 0:
                break

        if filters[index].targetURI:
            test = "yes"
        else:
            for aFilter in filters:
                aFilter.save()

else:
    formset = FilterFormSet(instance=controller)

return render_to_response('controller_details.html', {'formset':formset, 'controllerURI':controllerURI}, context_instance=RequestContext(request))
+1  A: 

UPDATE: If you intended to create a FormSet with Controller and Filter models where Filter holds a FK to the Controller, you need:

FilterFormSet = inlineformset_factory(Controller, Filter, form=FilterForm)

Note that in your code above, you're only passing the the Controller model class, which caused some confusion.

ars
Tks for your reply. I changed my code to be FilterFormSet = inlineformset_factory(Controller, form=FilterForm, extra=5) but now I'm getting this error: inlineformset_factory() takes at least 2 non-keyword arguments (1 given)
Przemek
Hi, see my update to the answer.
ars
Actually there is a foreign key relationship. A Controller contains one or more Filters.class Filter(Component): controller = models.ForeignKey(Controller) targetURI = models.ForeignKey('self', verbose_name='Target URI', null=True, blank=True) filterType = models.CharField('Type', max_length=64, choices=FILTER_TYPES, blank=False, default='avgFilter') order = models.IntegerField('Order')
Przemek
@Przemek: see update.
ars