【问题标题】:django model forms, display text for a foreign key (not using __str__ in model)django 模型表单,显示外键文本(不在模型中使用 __str__)
【发布时间】:2018-07-31 15:26:28
【问题描述】:

我有一个映射表,我将其作为另一个表的外键引用,即

映射表:

class DeviceCircuitSubnets(models.Model):
    device = models.ForeignKey(Device, on_delete=models.CASCADE)
    circuit = models.ForeignKey(Circuit, on_delete=models.CASCADE, blank=True, null=True)

然后在我的接口表中:

class InterfaceData(models.Model):
    device_circuit = models.ForeignKey(DeviceCircuit, verbose_name="Device", on_delete=models.CASCADE)
    interface_name = models.CharField(max_length=100, verbose_name='Interface name')
    dashboard = models.BooleanField(default=False, verbose_name="Display on monitoring dashboard?")
    wallboard = models.BooleanField(default=False, verbose_name="Display on wallboards?")

我正在为 forms.py 中的接口数据构建一个表单,但下拉列表的显示文本只是 DeviceCircuit 对象。我知道这是因为我没有设置 def str(self),但我的理解是,如果我这样做,我会对其他模型进行不必要的调用(即 str 将引用 device. hostname 和 circuit.circuit_type.circuit_type 等等我不想要的。

我只想在需要时更改下拉菜单的显示。

到目前为止,我已经过滤并重命名了该字段,但似乎无法设置显示,这可以使用模型表单吗?

class InterfaceDataForm(forms.ModelForm):
    class Meta:
        model = InterfaceData
        fields = ['device_circuit','interface_name','dashboard','wallboard']

    def __init__(self, *args, **kwargs):
        self.is_add = kwargs.pop("is_add", False)
        device_id = kwargs.pop("device_id")
        super(InterfaceDataForm, self).__init__(*args, **kwargs)
        self.fields['device_circuit'].queryset = DeviceCircuit.objects.filter(device_id=device_id) \
                                                                                        .select_related('device') \
                                                                                        .select_related('circuit') \
                                                                                        .select_related('circuit__circuit_type') \
                                                                                        .select_related('circuit__service_contact') \
                                                                                        .select_related('circuit__service_contact__provider') 
        self.fields['device_circuit'].label = 'Device / Circuit'

【问题讨论】:

  • 希望在下拉列表中显示什么文本?
  • 它将是 '{} - {} {}'.format(device.hostname,circuit.circuit_type, circuit.provider)

标签: django django-forms


【解决方案1】:

如果您希望下拉文本为'{} - {} {}'.format(device.hostname,circuit.circuit_type, circuit.provider),那么您是正确的,这将调用其他模型。但这真的有问题吗?如果您希望显示该信息,则必须在某个时候执行此操作。假设您在为 DeviceCircuit 调用 str 时使用 select/prefetch_related ,它应该是有效的。无论如何,“DeviceCircuit 对象”什么时候有用。

如果您仍然不想覆盖 str,那么您可以按照 docs 中的说明对 ModelChoiceField 进行子类化:

class DeviceCircuitField(forms.ModelChoiceField):

    def label_from_instance(self, device_circuit):
        circuit = device_circuit.circuit
        device = device_circuit.device
        return '{} - {} {}'.format(
            device.hostname, circuit.circuit_type, circuit.service_contact.provider
        )


class InterfaceDataForm(forms.ModelForm):

    class Meta:
        model = InterfaceData
        fields = ['device_circuit','interface_name','dashboard','wallboard']

    def __init__(self, *args, **kwargs):
        self.is_add = kwargs.pop("is_add", False)
        device_id = kwargs.pop("device_id")
        super(InterfaceDataForm, self).__init__(*args, **kwargs)
        self.fields['device_circuit'] = DeviceCircuitField(
            queryset=DeviceCircuit.objects.filter(device_id=device_id).select_related(
                'device', 'circuit', 'circuit__circuit_type', 'circuit__service_contact__provider'
            ),
            label='Device / Circuit'
        ) 

【讨论】:

    猜你喜欢
    • 2012-04-24
    • 2020-02-02
    • 2018-11-30
    • 2013-08-06
    • 1970-01-01
    • 2013-01-17
    • 1970-01-01
    • 1970-01-01
    • 2013-02-07
    相关资源
    最近更新 更多