ListField使用你可以使用的类型来重新研究它。但这有一些假设,例如你不在列表中存储复杂类型的事实。出于这个原因,我曾经
ast.literal_eval()强制只将简单的内置类型作为成员存储在ListField:
from django.db import modelsimport astclass ListField(models.TextField): __metaclass__ = models.Subfieldbase description = "Stores a python list" def __init__(self, *args, **kwargs): super(ListField, self).__init__(*args, **kwargs) def to_python(self, value): if not value: value = [] if isinstance(value, list): return value return ast.literal_eval(value) def get_prep_value(self, value): if value is None: return value return unipre(value) def value_to_string(self, obj): value = self._get_val_from_obj(obj) return self.get_db_prep_value(value)class Dummy(models.Model): mylist = ListField()
试一下:
>>> from foo.models import Dummy, ListField>>> d = Dummy()>>> d.mylist[]>>> d.mylist = [3,4,5,6,7,8]>>> d.mylist[3, 4, 5, 6, 7, 8]>>> f = ListField()>>> f.get_prep_value(d.numbers)u'[3, 4, 5, 6, 7, 8]'
在那里,列表以unipre字符串的形式存储在数据库中,并且在将列表拉回数据库时,它会通过进行运行
ast.literal_eval()。
CommaSeparatedIntegerField的替代方法,它允许你存储任何分隔的值。你还可以选择指定令牌参数。
from django.db import modelsclass SeparatedValuesField(models.TextField): __metaclass__ = models.Subfieldbase def __init__(self, *args, **kwargs): self.token = kwargs.pop('token', ',') super(SeparatedValuesField, self).__init__(*args, **kwargs) def to_python(self, value): if not value: return if isinstance(value, list): return value return value.split(self.token) def get_db_prep_value(self, value): if not value: return assert(isinstance(value, list) or isinstance(value, tuple)) return self.token.join([unipre(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)


