自定义Django字段以存储多个邮箱地址
我正在尝试在Django模型中添加一个字段,用来表示一系列电子邮件地址。我希望用户能在管理界面中输入一个用逗号分隔的地址列表,然后我的应用程序会解析这些地址,以便发送一系列电子邮件。
我现在的实现基本上能做到这一点,但有一个很大的限制。在管理界面中,如果我输入像 foo@example.com, bar@example.com
这样的字符串,它会正确地将其写入数据库,变成 [u'foo@example.com', u'bar@example.com']
。但是,管理界面显示的却是这个序列化的值,而不是人类可读的字符串。更重要的是,如果我编辑并保存记录,而没有做任何更改,这个转换会把 [u'foo@example.com', u'bar@example.com']
变成 [u"[u'foo@example.com'", u"u'bar@example.com']"]
。
我该如何将Python列表的表示形式转换回字符串,以便在管理界面中使用?这是否是 value_to_string
方法的目的,还是我需要在其他地方进行转换?
我现在的自定义模型字段如下:
class EmailListField(models.TextField):
__metaclass__ = models.SubfieldBase
def to_python(self, value):
if not value:
return
if isinstance(value, list):
return value
return [address.strip() for address in value.split(',')]
def get_db_prep_value(self, value):
if not value:
return
return ','.join(unicode(s) for s in value)
def value_to_string(self, obj):
value = self._get_val_from_obj(obj)
return self.get_db_prep_value(value)
这个字段是基于这里描述的 SeparatedValuesField
:http://www.davidcramer.net/code/181/custom-fields-in-django.html。
4 个回答
3
这个问题已经没有人讨论了,但你可以通过给你的 Python 变量添加特定的展示方式来实现这个功能。
class EmailDomainsListField(models.TextField):
__metaclass__ = models.SubfieldBase
class Presentation(list):
def __unicode__(self):
return u",".join(self)
def __str__(self):
return ",".join(self)
...
def to_python(self, value):
if not value:
return
if isinstance(value, EmailDomainsListField.Presentation):
return value
return EmailDomainsListField.Presentation([address.strip() for address in value.split(',')])
4
我参考了文档,但这是一个模型字段:
class MultiEmailField(models.TextField):
def to_python(self, value):
if not value:
return None # []
cleaned_email_list = list()
#email_list = filter(None, value.split(','))
email_list = filter(None, re.split(r';|,\s|\n', value))
for email in email_list:
if email.strip(' @;,'):
cleaned_email_list.append(email.strip(' @;,'))
print cleaned_email_list
cleaned_email_list = list(set(cleaned_email_list))
return ", ".join(cleaned_email_list)
def validate(self, value, model_instance):
"""Check if value consists only of valid emails."""
# Use the parent's handling of required fields, etc.
super(MultiEmailField, self).validate(value, model_instance)
email_list = value.split(',')
for email in email_list:
validate_email(email.strip())
3
我不会那样做。我会让你的 EmailListField
和电子邮件地址字段之间的关系是一对多的。