pythondjangodjango-formsdjango-querysetdjango-model-field

How do I fix Django returning 'self' not defined NameError on queryset filtering of ModelChoiceField?


I have 2 models, Type and Measure. Each Measure object has a typeid ForeignKey field that refers to the id field of a Type object. Each Type is viewed on it's own page where the id is passed through URL. urls.py

urlpatterns = [
    path('type/<int:id>', views.type, name='type'),
]

The view had been working with this as it is before I added the ModelChoiceField to the form.

views.py

def type(request, id):
    mytypes = Type.objects.all().values()
    mytype = Type.objects.get(id=id)
    mymeasures = Measure.objects.filter(typeid=id)
    template = loader.get_template('type.html')
    if request.method == 'GET':
        form = ConvForm(request.GET)
        # check whether it's valid:
        if form.is_valid():
            # process the data in form.cleaned_data as required
            # ...
            # redirect to a new URL:
            if request.from_type != None:
                redir = f"/type/{id}"        # create a form instance and populate it with data from the request:
            return HttpResponseRedirect(redir)

    # if a GET (or any other method) we'll create a blank form
    else:
        form = ConvForm(id)
    context = {
        'form' : form,
        'mytype': mytype,
        'mytypes' : mytypes,
        'mymeasures' : mymeasures
    }
    return HttpResponse(template.render(context, request))

It is once it imports the form that it runs into a problem with the following code.

forms.py

class ConvForm(forms.Form):
    from_value = forms.DecimalField(label='From Value', max_digits=256, decimal_places=255)
    from_measure = forms.ModelChoiceField(queryset=Measure.objects.none())

    class __init__(self, *args, **kwargs):
        id = kwargs.pop('id')
        super(ConvForm, self).__init__(*args, **kwargs)
        self.fields['from_measure'].queryset = Measure.objects.filter(typeid=id)

This is where the class init line produces the following error.

NameError: name 'self' is not defined

I have searched through several places that talk about how to queryset filter a ModelChoiceField, and they all use a very similar class init. I have gone over the code looking for errors that may be causing it.


Solution

  • constructor should be def not class

    your code should be like this

    class ConvForm(forms.Form):
        from_value = forms.DecimalField(label='From Value', max_digits=256, decimal_places=255)
        from_measure = forms.ModelChoiceField(queryset=Measure.objects.none())
    
        def __init__(self, *args, **kwargs):
            id = kwargs.pop('id')
            super(ConvForm, self).__init__(*args, **kwargs)
            self.fields['from_measure'].queryset = Measure.objects.filter(typeid=id)