Database Django、自动生成一对多表和数据库结构
我正在使用django作为一个网站,在那里我有一个包含用户、人员、位置、项目等的数据库。我知道我发现我需要一些额外的信息,这些信息需要一对多关系,比如这些表的别名 我应该(1)使用内容类型框架为所有这些创建一个通用别名表(最终可能会有数十亿行),还是(2)为每一行创建一个别名表。如果是后者,我如何通过添加一行这样的代码来自动创建这样的一对多表 “别名=Ailias()” 在每个模型中。我敢肯定,我刚才看到一个应用程序以这种方式运行,我想这是一个某种类型的回归应用程序。即使第二种方法不合适,我也很想知道怎么做。我不知道要寻找什么来解释这一点 我计划将Haystack与Solr一起添加到该方法中,因此方法2可能会在其中添加更多额外的工作。但我没有太多的经验,所以我可能是错的Database Django、自动生成一对多表和数据库结构,database,django,one-to-many,Database,Django,One To Many,我正在使用django作为一个网站,在那里我有一个包含用户、人员、位置、项目等的数据库。我知道我发现我需要一些额外的信息,这些信息需要一对多关系,比如这些表的别名 我应该(1)使用内容类型框架为所有这些创建一个通用别名表(最终可能会有数十亿行),还是(2)为每一行创建一个别名表。如果是后者,我如何通过添加一行这样的代码来自动创建这样的一对多表 “别名=Ailias()” 在每个模型中。我敢肯定,我刚才看到一个应用程序以这种方式运行,我想这是一个某种类型的回归应用程序。即使第二种方法不合适,我也很
PS:以方法1结束。在方法2中,我想做什么就做什么,轻松生成一对多字段。不确定这是最简单的方法,还是最好的方法。如果有人有更好的方法,我会很乐意去学习。我离django专家还有很长一段路要走,所以我可能会为了做我想做的事情而干预一些不必要的复杂事情 此示例创建了一种添加一对多别名关系的简单方法 别名管理器
class AliasManagerDescriptor(object):
def __init__(self, model,fkName):
self.model = model
self.fkName = fkName
def __get__(self, instance, owner):
if instance is None:
return AliasManager(self.model,self.fkName)
return AliasManager(self.model, self.fkName, instance)
class AliasManager(models.Manager):
def __init__(self, model,fkName, instance=None):
super(AliasManager, self).__init__()
self.model = model
self.instance = instance
#Name of FK linking this model to linked model
self.fkName=fkName
def get_query_set(self):
"""
Get query set, or only get instances from this model that is linked
to the chosen instance from the linked model if one is chosen
"""
if self.instance is None:
return super(AliasManager, self).get_query_set()
if isinstance(self.instance._meta.pk, models.OneToOneField):
#TODO: Checkif this part works, not checked
filter = {self.instance._meta.pk.name+"_id":self.instance.pk}
else:
filter = {self.fkName: self.instance.pk}
return super(AliasManager, self).get_query_set().filter(**filter)
def create(self,**kwargs):
"""
Create alias instances. If FK is not given then it is automatically set
to the chosen instance from the linked model
"""
if self.fkName not in kwargs:
kwargs[self.fkName]=self.instance
print kwargs
super(AliasManager, self).create(**kwargs)
别名模型
class Alias(object):
def contribute_to_class(self, cls, name):
self.manager_name = name
aliasModel = self.create_alias_model(cls)
descriptor = AliasManagerDescriptor(aliasModel,cls._meta.object_name.lower())
setattr(cls, self.manager_name, descriptor)
def create_alias_model(self, model):
"""
Creates a alias model to associate with the model provided.
"""
attrs = {
#'id': models.AutoField(primary_key=True),
"name": models.CharField(max_length=255),
#Not sure which to use of the two next methods
model._meta.object_name.lower(): models.ForeignKey(model),
#model._meta.object_name.lower(): AliasObjectDescriptor(model),
'__unicode__': lambda self: u'%s' % self.name,
'__module__': model.__module__
}
attrs.update(Meta=type('Meta', (), self.get_meta_options(model)))
name = '%s_alias' % model._meta.object_name
return type(name, (models.Model,), attrs)
def get_meta_options(self, model):
"""
Returns a dictionary of fields that will be added to
the Meta inner class.
"""
return {
}
"""class AliasObjectDescriptor(object):
def __init__(self, model):
self.model = model
def __get__(self, instance, owner):
values = (getattr(instance, f.attname) for f in self.model._meta.fields)
return self.model(*values)"""
人员模型-只需向模型中添加“alias=alias()”即可添加一对多别名字段
class Person(models.Model):
name = models.CharField(max_length=30,blank=True,null=True)
age = models.IntegerField(blank=True,null=True)
alias = Alias()
现在你我可以这样做:
per = Person(name="Per",age=99)
per.save()
per.alias.create(name="Mr.P")
per_alias = per.alias.all().values_list("name",flat=True)