我正在尝试将字段添加到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列表表示转换回字符串以便在admin中使用?这是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。
答案 0 :(得分:3)
我不会这样做。我会将与EmailListField
相关联的任何内容与电子邮件地址字段中的一对多联系起来。
答案 1 :(得分:3)
问题已经死了,但你可以通过将特定的演示文稿添加到你的python val
来实现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(',')])
答案 2 :(得分:1)
我的基础是文档,但它是一个模型字段:
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 :(得分:1)
以下是模型字段,其中包含每封电子邮件的验证和正确的管理处理。基于eviltnan和AndrewF的答案。
from django.core import validators
from django.db import models
class EmailListField(models.CharField):
__metaclass__ = models.SubfieldBase
class EmailListValidator(validators.EmailValidator):
def __call__(self, value):
for email in value:
super(EmailListField.EmailListValidator, self).__call__(email)
class Presentation(list):
def __unicode__(self):
return u", ".join(self)
def __str__(self):
return ", ".join(self)
default_validators = [EmailListValidator()]
def get_db_prep_value(self, value, *args, **kwargs):
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)
def to_python(self, value):
if not value:
return
if isinstance(value, self.Presentation):
return value
return self.Presentation([address.strip() for address in value.split(',')])