Skip to content
Advertisement

Setting a dropdowns values based on a different model selection

I currently have a model with 2 fields: Name & Number of Units

When the first field is selected e.g. Name = Name1 I would like to display the Number Of Units saved in association with that model. e.g. Name1 has 50 units then the second < select > will show the number a list from 1 – 50 because Name1 has 50 units.

When I do this with my code currently , it lists the max number of units for every model entry instead

Please see the below code:

template.html:

<form>
    <select  name="Complex">
        {% for x in model %}
            <option value="{{ x }}">{{ x.ComplexName }}</option>
        {%  endfor %}
    </select>> Complex


    <select>
        {% for x in model %}
            <option value="{{ x.NumberOfUnits }}">{{ x.NumberOfUnits }}</option>
        {% endfor %}
    </select>

</form>

Views.py:

def customerDetails(request):
    model = ComplexListClass.objects.all().order_by('ComplexName')

    content = {'model': model}
    return render(request, 'main/customerDetails.html', content)

Models.py:

class ComplexListClass(models.Model):
    ComplexName = models.CharField(choices=complex_list , max_length =  50 ,default='1' , unique=True)
    NumberOfUnits = models.IntegerField(max_length=2 , blank=False , default=1 )

    def __str__(self):
        return (self.ComplexName)

Advertisement

Answer

If you don’t want to go down the AJAX route, I’d suggest adding the maximum number of units to the first <select> and making the NumberOfUnits an Integer input field (with a minimum value validator of 1?). Form validation can further check that the number is not greater than the number available, which the user was already told about. Raise a validation error about exceeding the maximum.

<form>
<select  name="Complex">
    {% for x in model %}
        <option value="{{ x }}">
            {{ x.ComplexName }} ({{ x.NumberOfUnits }} available </option>
    {%  endfor %}
</select>> Complex

{{form.number_of_units}}

and in your form override the clean method to check

    def clean(self):
        #get clean values from the form
        cleaned_data=super().clean()

        complex_name = cleaned_data['ComplexName')

        # t.b.s. get the maximum_units for this name here 

        if cleaned_data['NumberOfUnits'] > maximum_units:
            raise forms.ValidationError(
                f"Only {maximum_units} available for {complex_name}" )
        return cleaned_data
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement