0

我定义了以下类,它们基本上定义了一个 Node 类。每个节点可以有多个 NodeIntf 分配给它。每个 NodeIntf 可以有多个 NodeIntfIpaddr 分配给它。其中一个 NodeIntfIpaddr 可能被分配为 Node 对象上的 mgmt_ipaddr 属性。其中之一可能分配给 mgmt_ipaddr_v6 属性。现在在我的模板中,我基本上有一个用于接口的嵌套表,我想使用单选按钮选择器来选择为 Node 对象上的 mgmt_ipaddr(_v6) 属性选择的 ipaddrs,但我不太确定怎么做。我认为,当我遍历 ipaddr_formset 时,我必须检查该 ipaddr 是否代表选定的 mgmt_ipaddr,但我不知道该怎么做。任何帮助,将不胜感激。

class Node(models.Model):
    name = models.CharField(max_length=64, primary_key=True)
    mgmt_ipaddr = models.ForeignKey('NodeIntfIpaddr', null=True, on_delete=models.SET_NULL)
    mgmt_ipaddr_v6 = models.ForeignKey('NodeIntfIpaddr', null=True, on_delete=models.SET_NULL)

class NodeIntf(models.Model):
    intf = models.CharField(max_length=32)
    node = models.ForeignKey('Node', on_delete=models.CASCADE)
    class Meta:
        unique_together = ('node', 'intf')

class NodeIntfIpaddr(models.Model):
   node_intf = models.ForeignKey('NodeIntf', on_delete=models.CASCADE)
   ipaddr = InetAddressField()
   class Meta:
       unique_together = ('node_intf', 'ipaddr')

class NodeForm(ModelForm):
    class Meta:
        model = Node

class NodeIntfForm(ModelForm):
    class Meta:
        model = NodeIntf

class NodeIntfIpAddrForm(ModelForm):
    class Meta:
        model = NodeIntfIpaddr

NodeIntfIpaddrFormSet = modelformset_factory(NodeIntfIpaddr,
    form=NodeIntfIpAddrForm, extra=0)

class BaseNodeIntfFormSet(BaseInlineFormSet):
    def add_fields(self, form, index):
        super(BaseNodeIntfFormSet, self).add_fields(form, index)
        instance = self.get_queryset()[index]
        pk_value = instance.pk
        form.ipaddr_formset = NodeIntfIpaddrFormSet(
            queryset=NodeIntfIpaddr.objects.filter(node_intf=pk_value),
            prefix='INTF_%s' % pk_value)

NodeIntfFormSet = inlineformset_factory(Node, NodeIntf,
    form=NodeIntfForm, formset=BaseNodeIntfFormSet, extra=0)

class NodeUpdateView(UpdateView):
    form_class = NodeForm
    model = Node
    def get_context_data(self, **kwargs):
        c = super(NodeUpdateView, self).get_context_data(**kwargs)
        node = self.get_object()
        c['action'] = reverse('node-update', kwargs={'pk': node.name})
        if self.request.POST:
            node_intfs = NodeIntfFormSet(self.request.POST, instance=node)
            if node_intfs.is_valid():
                addrs = node_intfs.save_all()
        else:
            node_intfs = NodeIntfFormSet(instance=node)
        c['node_intfs_formset'] = node_intfs
        return c

模板片段:

  <table class='node_intfs'>
      <thead>
        <tr class='node_intf'>
          <th colspan='2'></th>
          <th>Name</th>
          <th></th>
        </tr>
        <tr class='node_intf_ipaddr'>
          <th>IPv4 Mgmt<br><label><input type='radio' name='mgmt_ipaddr' value=''{{ node.mgmt_ipaddr|yesno:', checked' }}>None</label></th>
          <th>IPv6 Mgmt<br><label><input type='radio' name='mgmt_ipaddr_v6' value=''{{ node.mgmt_ipaddr_v6|yesno:', checked' }}>None</label></th>
          <th colspan='2'></th>
        </tr>
      </thead>
      <tbody>
{% for node_intf_form in node_intfs_formset %}
        <tr class='node_intf'>
          <td colspan='2'></td>
          <td>{{ node_intf_form.intf }}</td>
          <td></td>
        </tr>
{% if node_intf_form.ipaddr_formset %}
{% for ipaddr_form in node_intf_form.ipaddr_formset %}
        <tr class='node_intf_ipaddr'>
          <td>TODO</td>                                  <---- These are what I can't figure out
          <td>TODO</td>                                  <---- These are what I can't figure out
          <td></td>
          <td>{{ ipaddr_form.ipaddr }}</td>
        </tr>
{% endfor %}
{% endif %}
{% endfor %}
      </tbody>
    </table>
4

1 回答 1

0

通过在我的模板中使用以下内容,我能够做我需要的事情:

<td class='center'><input type='radio' name='mgmt_ipaddr' value='{{ ipaddr_form.instance.id }}'{% if node.mgmt_ipaddr_id == ipaddr_form.instance.id %} checked='checked'{% endif %}</td>
<td class='center'><input type='radio' name='mgmt_ipaddr_v6' value='{{ ipaddr_form.instance.id }}'{% if node.mgmt_ipaddr_v6_id == ipaddr_form.instance.id %} checked='checked'{% endif %}</td>

这会将来自 Node 对象的 mgmt_ipaddr(_v6)_id 与绑定到单个 ipaddr 表单的实例的 id 进行比较,可通过 ipaddr_form.instance.id 访问。

为了完整起见,我之前还缺少 node_intf_forms 和 ipaddr_forms 的 management_form。

于 2013-05-03T02:20:24.420 回答