Заполнение/фильтрация одного <select> другим <select>

У меня есть форма для создания проектов в моем приложении. В этой форме пользователь должен выбрать клиента в одной форме, а затем ферму в другой. Как сделать так, чтобы при выборе клиента, в следующем предлагались только варианты из ферм, которые принадлежат выбранному клиенту? Я считаю, что это невозможно сделать с помощью только Django, я прав?

упрощенные модели.py

class Project(models.Model):
            farm = models.ManyToManyField(Farm, related_name='farm_name',verbose_name='Propriedade beneficiada')
            client = models.ForeignKey(Clients, on_delete=models.CASCADE, related_name='project_client',default=None,null=True, verbose_name='Cliente')
        

class Farm(models.Model):
               client = models.ForeignKey(Clients, on_delete=models.CASCADE, related_name='client', null=True, default=None)
               name = models.CharField(max_length=100, verbose_name='Nome')

forms.py

class NewProjectForm(ModelForm):
    class Meta:
        model = Project
        fields = ['owner','farm','warranty','modal','harvest_year','culture','value','final_date']

    def __init__(self, *args,**kwargs):
        super(NewProjectForm, self).__init__(*args,**kwargs)
        self.fields['value'].required = False
        self.fields['final_date'].required = False
        self.fields['owner'].queryset = Owner.objects.all().order_by('name')
        farm_query = Farm.objects.all().order_by('name')
        self.fields['farm'].queryset = farm_query
        self.fields['warranty'].queryset = farm_query
        self.fields['final_date'].widget.attrs['data-mask'] = "00/00/0000"

        for field_name, field in self.fields.items():
            field.widget.attrs['class'] = 'form-control'

Я нашел ответ, который не требует много jquery и использует логику в forms.py, это было именно то, что я искал (поскольку я понимаю только основы Java). Вот обновленный код:

forms.py

class NewProjectForm(ModelForm):
    class Meta:
        model = Project
        fields = ['client','owner','farm','warranty','modal','harvest_year','culture','value','final_date']

    def __init__(self, *args,**kwargs):
        super(NewProjectForm, self).__init__(*args,**kwargs)
        self.fields['value'].required = False
        self.fields['final_date'].required = False
        self.fields['owner'].queryset = Owner.objects.all().order_by('name')
        self.fields['final_date'].widget.attrs['data-mask'] = "00/00/0000"

        self.fields['farm'].queryset = Farm.objects.none()
        if 'client' in self.data:
            try:
                client_id = int(self.data.get('client'))
                self.fields['farm'].queryset = Farm.objects.filter(client_id=client_id).order_by('name')
            except (ValueError, TypeError):
                pass
        elif self.instance.pk:
            self.fields['farm'].queryset = self.instance.client.farm_set.order_by('name')

        for field_name, field in self.fields.items():
            field.widget.attrs['class'] = 'form-control'

url.py

(...)
path('new/',views.project_new,name='project_new'),

path('ajax/load-farms/',views.load_farms,name='ajax_load_farms'),     #AJAX

views.py

@login_required
def project_new(request):
    clients = Clients.objects.all().order_by('name')
    farms = Farm.objects.all().order_by('name')
    form = NewProjectForm()
    return render(request,'project_new.html',{'clients':clients,
                                              'farms':farms,
                                               'form':form})

def load_farms(request):
    client_id = request.GET.get('client_id')
    farms = Farm.objects.filter(client_id=client_id)
    return render(request, 'farm_dropdown_list_options.html', {'farms':farms})

farm_dropdown_list_options.html

<option value="">-----</option>
{% for farm in farms %}
    <option value="{{ farm.pk }}">{{ farm.name }}</option>
{% endfor %}

project_new.html

{% extends 'base.html' %}

{% block title %}
    <title>Novo Projeto</title>
{% endblock %}

{% block content %}

    <form name="form" id="form" method="POST" data-farm-url="{% url 'ajax_load_farms' %}">
        {% csrf_token %}
        {{ form }}
        <input type="submit" value="Enviar">
    </form>

<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script>
    $('#id_client').change(function()
    {
        const url = $('#form').attr('data-farm-url');
        const clientId = $(this).val();

        $.ajax({
            url: url,
            data: {
                'client_id': clientId
            },
            success: function(data){
                $("#id_farm").html(data);
                console.log('opa');
            }
        });
    });
</script>
{% endblock %}

Я ОСНОВАЛ ЭТУ ЛОГИКУ В: GIT

Вернуться на верх