【问题标题】:Is it possible to add a variable to Django Model Field.choices?是否可以向 Django Model Field.choices 添加变量?
【发布时间】:2013-06-05 02:30:28
【问题描述】:

是否可以在 Django Model Field.choices 中添加变量?

当我必须静态添加它时,我失去了功能。

IP_CHOICES = (
    ('192.168.1.0', '192.168.1.0'),
)

ip_address = models.IPAddressField(choices=IP_CHOICES, unique=True, blank=True)

我使用名为 IPy 的 Python IP 解释器来计算正确的 IP 块。

ip = IP(self.network + slash)

for rangeip in enumerate(ip[2:-1]):

    IP_CHOICES = (
        ("%s" %rangeip, "%s" %rangeip)
    )

这可能吗?如果是这样,请帮助。过去一周一直试图破解它,但无处可去。任何帮助表示赞赏。

请查看模型类。

#IP Block Class
class IP_block(models.Model):

    network = models.IPAddressField(unique=True)
    slash = models.ForeignKey(Subnet, verbose_name='CIDR')
    subnet = models.CharField(max_length=64, blank=True)
    gateway_ip = models.CharField(max_length=64, blank=True)
    broadcast_ip = models.CharField(max_length=64, blank=True)
    ip_range = models.TextField(blank=True, verbose_name='Available IP Range')
    dslam = models.ManyToManyField(Dslam, verbose_name='Dslam', blank=True)

    #ip block and range save function


    def save(self, *args, **kwargs):

        slash = unicode(self.slash)

        broadcast = IP(self.network + slash).broadcast()
        subnet = IP(self.network+slash).strNetmask()

        self.broadcast_ip = broadcast
        self.subnet = subnet

        ip = IP(self.network + slash)

        for gateway in ip[1]:
            self.gateway_ip = gateway

        #rangeip for loop

        ip = IP(self.network + slash)


        if self.ip_range:
            print 'no override'

        else:

            for rangeip in ip[2:-1]:
                self.ip_range += "%s\n" %rangeip

                IP_CHOICE = "(%s" %rangeip + ", %s)," %rangeip

                #ip_list select 

                ip_list = models.CharField(choices=IP_CHOICE, max_length=128, blank=True)

        super(IP_block, self).save(*args, **kwargs)


    class Meta:
        verbose_name_plural = 'IP Blocks'

    def __unicode__(self):
        return self.network         

【问题讨论】:

  • 您遇到的错误是什么? IP(self.network + slash) 返回什么?
  • 另外,你可以这样做:choices = tuple(zip(ip, ip))
  • ip = 192.168.1.0/27 - 这就是 ip 块。
  • 但是我想将我的文本字段中的列表添加到选项中。所以继续尝试,我得到 TypeError: zip argument #1 must support iteration。
  • 哦.. 我不知道返回类型。在 iPy 中有没有办法将 ips 的范围作为一个列表?

标签: django list model tuples choice


【解决方案1】:

这里有很多相当基本的错误。例如,在您建议的语法中:

for rangeip in enumerate(whatever):
    IP_CHOICES = (do_something)

您应该很明显,每次循环都只是简单地覆盖 IP_CHOICES。在循环结束时,它将仅具有最后一次迭代的值,该值本身并不适合choices

您多次使用相同的模式。请考虑一下它实际上在做什么。

但是在你的保存函数中还有一个更严重的错误,你有这行:

ip_list = models.CharField(choices=IP_CHOICE, max_length=128, blank=True)

我完全不知道你认为这是在做什么。您不能在保存方法的中间定义字段。你可以设置一个字段的值,但你不能突然定义一个新字段(再次,请想想:这将如何与数据库一起工作?记住字段是类 em> 级属性:该模型的所有实例都需要具有相同的字段选择)。

几乎不可能理解你真正想要做什么。一旦用户在另一个字段 (ip_range) 中设置了范围,我认为您正在尝试为模型中的一个字段 (ip_list) 提供 IP 地址选择。 (如果您事先明确说明,那将会很有用。)

这样做的地方是在表单中,而不是在模型中。在模型字段上设置choices 实际上只是在从该模型自动创建的表单上设置它们的快捷方式,但是如果您需要做一些动态的事情,您需要自己定义表单并将逻辑放在那里。我想应该是这样的:

class IPBlockForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(IPForm, self).__init__(*args, **kwargs)
        if self.instance and self.instance.ip_range:
            ip_list_choices = get_ip_list_from_wherever(self.instance_ip_range)
            self.fields['ip_list'] = forms.ChoiceField(choices=ip_list_choices)

    class Meta:
        model = IP_block

但当然,您首先需要修复 save 方法中的其他逻辑错误,我在上面提到过。

【讨论】:

  • 我明天会试一试,会让你知道会发生什么。感谢您的帮助。
  • 我让它与解决方案一起工作,但是我唯一需要工作的是列表。在选择字段中,它会在同一行显示所有 IP。我需要让 IP 地址显示为多项选择而不是一项选择。感谢您的所有帮助!
  • 你必须积极地做一些事情来把它放在一行上,因为一个正常的循环只会输出一个已经是正确格式的元组列表。但是,您可能需要在一个新问题中显示一些代码。
猜你喜欢
  • 2021-09-24
  • 1970-01-01
  • 2019-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 2011-09-30
  • 1970-01-01
相关资源
最近更新 更多