title: Django dependant filters using json list variable contained within a foreign key
body: <p>I have a form that a user can fill in. What I want is a dependant dropdown menu such that when a router (ce_hostname) is selected, the ports (l2_interfaces) for that router are selectable from the second dropdown (ce_wan_port). The list of ports are stored as a json list in the router and the router is stored as a foreign key.</p>
  <p>models.py</p>
  <pre><code>#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=&quot;CE Hostname&quot;, help_text=&quot;Hostname of router.&quot;)
      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=&quot;CE Hostname&quot;, help_text=&quot;Hostname of CE router.&quot;)
      ce_wan_port = models.CharField(max_length=500, null=True, blank=True)
  </code></pre>
  <p>For the purposes of my dropdown, the ce_wan_port should be a dropdown menu of the l2_interfaces, which appears after a ce_hostname is selected.</p>
  <p>Example l2_interfaces data</p>
  <pre><code>[
      &quot;Gi0/0/0&quot;,
      &quot;Gi0/0/1&quot;,
      &quot;Gi0/0/2&quot;
  ]
  </code></pre>
  <p>forms.py</p>
  <pre><code>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,)
  </code></pre>
  <p>This is currently filtering for ce_hostname objects within the same order.</p>
  <p>views.py</p>
  <pre><code>@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)
  </code></pre>
  <p>I tried sending the ce_hostname variable, but it does not make sense for me to do this as it can change each time the user changes the dropdown menu, not just on class init or post.</p>
  <p>Here is my html.</p>
  <pre><code>{% extends &quot;orchestration/base.html&quot; %}
  {% load static %}
  {%load crispy_forms_tags %}
  {% block content %}
  
  &lt;h1&gt;CE PE WAN Link Definition&lt;/h1&gt;
  &lt;div class=&quot;row&quot;&gt;
          &lt;div class=&quot;col-md-15&quot;&gt;
                  &lt;div class=&quot;card card-body&quot;&gt;
  
                          &lt;form action=&quot;&quot; method=&quot;POST&quot;&gt;
                                  {% csrf_token %}
                                  {{ce_pe_form|crispy}}
                                  &lt;p&gt;&lt;/p&gt;
                                  &lt;input type=&quot;submit&quot; name=&quot;Submit&quot;&gt;
                          &lt;/form&gt;
  
                  &lt;/div&gt;
          &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  <p>Edit:</p>
  <p>I am little further forward, but still can't figure out how to piece this together.</p>
  <p>In my views.py I am able to get the objects I want and print them out. From this, I can see how I could get the correct list from the selected dropdown.</p>
  <pre><code>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_hostname = request.POST.get('ce_hostname')
          ce_dropdown = Ce_Base.objects.get(id=ce_hostname)
          print(ce_dropdown.l2_interfaces)
  </code></pre>
  <p>In my forms.py, I am able to override the choices. I think this is what I want to do, but I am not sure how to do this dynamically as the user selects the ce_hostname from the dropdown.</p>
  <pre><code>class Ce_PeForm(ModelForm):
          class Meta:
                  model = Ce_Pe
                  fields = ['ce_hostname', 'pe_hostname', 'px_hostname', 'vrf', 'ce_wan_port', 'ce_local_device', 'ce_local_device_port', 'pe_wan_port', 'pe_local_device', 'pe_local_device_port', 'wan_vlan', 'outer_vlan', 'idn', 'vrf_22_co
  st']
  
          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,)
  
              #self.fields['ce_wan_port'].filter(data)
              self.fields['ce_wan_port'].choices = [('Gi0/0','Gi0/0'), ('Gi0/1','Gi0/1')]
  </code></pre>