Home > Blockchain >  Setting a dropdowns values based on a different model selection
Setting a dropdowns values based on a different model selection

Time:10-30

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)

CodePudding user response:

Since Django goes to sleep between request, you cannot have it serve different values based on a selection(even though it looks very simple and a much in use scenario).. So you will have to use a way around like passing the dropdown values as AJAX if you want to dynamically show the dropdown options...

The below link shows an easy implementation of what you are looking for,

Django chained dropdowns

CodePudding user response:

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
  • Related