Django dependant filters using json list variable contained within foreign key

У меня есть форма, которую может заполнить пользователь. Мне нужно зависимое выпадающее меню, чтобы при выборе маршрутизатора (ce_hostname) порты (l2_interfaces) для этого маршрутизатора можно было выбрать из второго выпадающего меню (ce_wan_port). Список портов хранится как json-список в маршрутизаторе, а маршрутизатор хранится как внешний ключ.

models.py

#Unique order. Top of heirachy tree
class Order(models.Model):
    order_name = models.CharField(max_length=100, unique=True)#, null=True, blank=True)                         #Unique name of order

#For CE router definition. Required for all orders.
class Ce_Base(models.Model):
    ce_hostname = models.CharField(max_length=15, validators=[CE_HOSTNAME_REGEX], verbose_name="CE Hostname", help_text="Hostname of router.")
    l2_interfaces = JSONField(null=True)                                                                        #Layer 2 interfaces

#For defining WAN links
class Ce_Pe(models.Model):

    order_reference = models.ForeignKey(Order, null=True, on_delete=models.CASCADE)                             #Order reference
    ce_hostname = models.ForeignKey(Ce_Base, null=True, on_delete=models.CASCADE, verbose_name="CE Hostname", help_text="Hostname of CE router.")
    ce_wan_port = models.CharField(max_length=500, null=True, blank=True)

Для целей моего выпадающего списка, ce_wan_port должен быть выпадающим меню l2_interfaces, которое появляется после выбора имени ce_hostname.

Пример l2_interfaces data

[
    "Gi0/0/0",
    "Gi0/0/1",
    "Gi0/0/2"
]

forms.py

class Ce_PeForm(ModelForm):
        class Meta:
                model = Ce_Pe
                fields = ['ce_hostname', 'ce_wan_port',]

        def __init__(self, *args, order_reference, **kwargs):
            super().__init__(*args, **kwargs)
            order_id = str(order_reference.id)
            self.fields['ce_hostname'].queryset = Ce_Base.objects.filter(order_reference=order_id,)

В настоящее время выполняется фильтрация объектов ce_hostname в том же порядке.

views.py

@login_required
def addCe_Pe(request, pk_test):
    order = Order.objects.get(id=pk_test)
    ce_pe_form = Ce_PeForm(order_reference=order)
    if request.method == 'POST':
        ce_pe_form = Ce_PeForm(request.POST, order_reference=order)
        ce_pe_form.instance.order_reference = order
        if ce_pe_form.is_valid():
            ce_pe_form.save()
            return redirect('/')

    context = {'ce_pe_form':ce_pe_form}
    return render(request, 'orchestration/ce_pe_form.html', context)

Я пытался отправить переменную ce_hostname, но мне нет смысла делать это, так как она может меняться каждый раз, когда пользователь меняет выпадающее меню, а не только при инициализации класса или в посте.

Вот мой html.

{% extends "orchestration/base.html" %}
{% load static %}
{%load crispy_forms_tags %}
{% block content %}

<h1>CE PE WAN Link Definition</h1>
<div class="row">
        <div class="col-md-15">
                <div class="card card-body">

                        <form action="" method="POST">
                                {% csrf_token %}
                                {{ce_pe_form|crispy}}
                                <p></p>
                                <input type="submit" name="Submit">
                        </form>

                </div>
        </div>
</div>

Форма создается только один раз во время рендеринга шаблона. Для манипуляций с полем выбора вам придется использовать JavaScript. Либо вы отображаете все возможные маршрутизаторы и их интерфейсы в теге script вашего html, который может быть доступен через js-файл, либо вы размещаете вызов AJAX, основанный на выборе маршрутизатора, чтобы вернуть соответствующие варианты портов и заполнить поле данными из ответа.

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