目前,我的代码中有很多类似于以下内容的python对象:
class MyClass(): def __init__(self, name, friends): self.myName = name self.myFriends = [str(x) for x in friends]
现在,我想将其转换为Django模型,其中self.myName是字符串字段,而self.myFriends是字符串列表。
from django.db import models class myDjangoModelClass(): myName = models.CharField(max_length=64) myFriends = ??? # what goes here?
由于列表是python中如此常见的数据结构,因此,我希望其中有一个Django模型字段。我知道我可以使用ManyToMany或OneToMany关系,但是我希望避免代码中的额外间接访问。
将这种关系更好地表示为Friends表的一对多外键关系吗?我知道这myFriends只是字符串,但我认为更好的设计是创建一个Friend模型,并MyClass在结果表中包含外键。
Friends
myFriends
Friend
MyClass
“过早的优化是万恶之源。” 牢记这一点,让我们开始吧!一旦你的应用达到特定点,对数据进行非规范化就非常普遍。如果做得正确,它可以节省大量昂贵的数据库查找,但要多花一些工夫。
要返回list朋友名称,我们需要创建一个自定义Django Field类,该类在访问时将返回一个列表。
list
David Cramer在他的博客上发布了有关创建SeperatedValueField的指南。这是代码:
from django.db import models class 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([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)
此代码的逻辑处理从数据库到Python的序列化和反序列化值,反之亦然。现在,你可以轻松地导入并使用模型类中的自定义字段:
from django.db import models from custom.fields import SeparatedValuesField class Person(models.Model): name = models.CharField(max_length=64) friends = SeparatedValuesField()