gpt4 book ai didi

python - 为什么克隆 FloatField 的这个子类(带有添加的验证器)会抛出异常?

转载 作者:行者123 更新时间:2023-12-01 01:48:44 24 4
gpt4 key购买 nike

我是 Python 和 Django 新手。

我希望我的模型具有经过范围验证的 float 。来自 this answer我写的是:

class FloatRangeField (FloatField):
"""A FloatField constrained to a given range."""

def __init__ (self, minimum, maximum, **kwargs):

minmax = [MinValueValidator (minimum), MaxValueValidator (maximum)]

print ("\n\t\tFloatRangeField({},{})".format(minimum,maximum)) # (A)
FloatField.__init__ (self, validators = minmax, **kwargs)
print ("\t\tFINISHED\n")

这导致 python3 manage.py migrate 中出现错误,我将其范围缩小到 clone()称呼。演示:

print ("HERE 1")
tmp1 = FloatRangeField (10, 20)
print ("HERE 2")
tmp2 = FloatRangeField (10, 20)
print ("HERE 3")
tmp3 = tmp1.clone () # (B)
print ("HERE 4")

它从 # (B) 行抛出异常。奇怪的是,当发生这种情况时,行# (A)处的跟踪打印。这是输出:

HERE 1

FloatRangeField(10,20)
FINISHED

HERE 2

FloatRangeField(10,20)
FINISHED

HERE 3
Traceback (most recent call last):
File "manage.py", line 15, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/lib/python3.5/dist-packages/django/core/management/__init__.py", line 371, in execute_from_command_line
utility.execute()

[...snip...]

tmp3 = tmp1.clone ()
File "/usr/local/lib/python3.5/dist-packages/django/db/models/fields/__init__.py", line 470, in clone
return self.__class__(*args, **kwargs)
TypeError: __init__() missing 2 required positional arguments: 'minimum' and 'maximum'

以及 # (A) 没有打印任何内容的奇怪现象,这与我在 migrate 期间看到的错误相同。如果我取出tmp1=...填充并运行migrate ,回溯看起来像这样

Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/django/db/migrations/state.py", line 411, in from_model
fields.append((name, field.clone()))
File "/usr/local/lib/python3.5/dist-packages/django/db/models/fields/__init__.py", line 470, in clone
return self.__class__(*args, **kwargs)

[...snip...]

FloatField.__init__ (self, validators = minmax, **kwargs)
TypeError: __init__() got multiple values for keyword argument 'validators'

为什么会出现这种情况以及我应该如何实现 FloatRangeField以便封装最小/最大验证器?

最佳答案

就像documentation on custom model fields中写的那样:

If you add a new keyword argument, you need to write code to put its value into kwargs yourself (...)

所以你还应该添加一个解构函数。这是必要的,例如在迁移文件中表示此字段:

class FloatRangeField (FloatField):
"""A FloatField constrained to a given range."""

def __init__ (self, minimum, maximum, **kwargs):
<b>self.minimum = minimum</b>
<b>self.maximum = maximum</b>
minmax = [MinValueValidator (minimum), MaxValueValidator (maximum)]
FloatField.__init__ (self, validators = minmax, **kwargs)

def deconstruct(self):
result = __, __, __, kwargs = super(FloatRangeField, self).deconstruct()
<b>kwargs['minimum'] = self.minimum</b>
<b>kwargs['minimum'] = self.maximum</b>
<b>del kwargs['validators']</b>
return result

请注意,您最好不要使用 validators = minmax 作为参数,因为这意味着如果用户将 validator 参数用于您的 FloatRangeField 构造函数,会出现参数冲突。

例如,可以附加我们的minmax验证器到已经存在的验证器,然后当我们想要解构它时将它们从验证器中弹出:

class FloatRangeField (FloatField):
"""A FloatField constrained to a given range."""

def __init__ (self, minimum, maximum, **kwargs):
self.minimum = minimum
self.maximum = maximum
<b>old_validators = kwargs.get('validators', [])</b>
minmax = [MinValueValidator (minimum), MaxValueValidator (maximum)]
<b>minmax += old_validators</b>
<b>kwargs['validators'] = minmax</b>
FloatField.__init__ (self, **kwargs)


def deconstruct(self):
result = __, __, __, kwargs = super(FloatRangeField, self).deconstruct()
kwargs['minimum'] = self.minimum
kwargs['minimum'] = self.maximum
<b>kwargs['validators'] = kwargs['validators'][2:]</b>
return result

因此,我们在 deconstruct(..) 函数中删除了前两个验证器(我们在 __init__(..) 函数中添加了它们)。

关于python - 为什么克隆 FloatField 的这个子类(带有添加的验证器)会抛出异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50951852/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com