【发布时间】:2019-08-09 06:41:19
【问题描述】:
我需要在 Django 模型中存储一个复数。对于那些忘记的人,这仅仅意味着Z=R+jX,其中 R 和 X 是表示复数的实部和虚部的实数。会有单独的号码,以及需要存储的列表。到目前为止,我的搜索还没有为列表提供好的解决方案,所以我打算让数据库将列表作为单独的记录来处理。
我看到了两个存储复数的选项:
1) 创建自定义字段:class Complex(models.CharField)
这将允许我自定义该字段的所有方面,但如果要正确完成,那将是大量额外的验证工作。主要优点是单个数字由表中的单个字段表示。
2) 让每个复数由一行表示,float 字段表示实部 R,另一个 float 字段表示虚部 X。这种方法的缺点是我会需要编写一些转换器来从组件中创建一个复数,反之亦然。好处是数据库只会将其视为另一条记录。
这个问题过去肯定已经解决了,但我找不到任何好的参考资料,更不用说 Django 的特别之处了。
这是我在该领域的第一次破解,它基于我发现的另一个涉及一些字符串操作的示例。我不清楚应该如何以及在何处执行各种验证(例如通过添加 +0j 将简单的浮点数强制为复数)。我还打算添加表单功能,以便该字段的行为类似于浮点字段,但有额外的限制或要求。
我尚未测试此代码,因此可能存在问题。它基于this SO question中答案的代码。运行代码后,似乎方法名称发生了一些变化。
What is the most efficient way to store a list in the Django models?
class ComplexField(models.CharField):
description = 'A complex number represented as a string'
def __init__(self, *args, **kwargs):
kwargs['verbose_name'] = 'Complex Number'
kwargs['max_length'] = 64
kwargs['default'] = '0+0j'
super().__init__(*args, **kwargs)
def to_python(self, value):
if not value: return
if isinstance(value, complex):
return value
return complex(value)
def get_db_prep_value(self, value):
if not value: return
assert(isinstance(value, complex))
return str(item)[1:-1]
def value_to_string(self, obj):
value = self._get_val_from_obj(obj)
return self.get_db_prep_value(value)
【问题讨论】:
-
听起来您正在准确描述自定义字段要解决的场景。最好让 to/from 转换尽可能靠近数据库,这样您就不必记住在模板或视图中将字符串转换为复数。
-
好的,我需要为自定义字段找到一个很好的示例。我很惊讶在我的搜索中没有弹出任何内容。 “复杂”返回的大部分内容都被视为“困难”,因此并不容易。
-
只要您不需要以字符串以外的任何其他方式查询 ComplexField,您的方法看起来不错。如果您需要以更复杂的方式进行查询,它会变得更加复杂。
标签: python django django-models django-custom-field