Python Django从类继承
我在开发Django网站时遇到了问题Python Django从类继承,python,django,inheritance,Python,Django,Inheritance,我在开发Django网站时遇到了问题 from django.db import models class TitlePost(models.Model): title_name = models.CharField(max_length=100, unique=True) title_body = models.TextField(max_length=30000) title_why = models.TextField(max_length=250, null=T
from django.db import models
class TitlePost(models.Model):
title_name = models.CharField(max_length=100, unique=True)
title_body = models.TextField(max_length=30000)
title_why = models.TextField(max_length=250, null=True)
title_publication_date = models.DateTimeField('date')
likes = models.IntegerField(default=0)
dislikes = models.IntegerField(default=0)
def __unicode__(self):
return self.title_name
class TopTitlesPostPage(models.Model):
title_post = models.OneToOneField(TitlePost)
hello = models.CharField(max_length=100, unique=True)
def __unicode__(self):
return self.hello
class NewTitlesPostPage(models.Model):
title_post = models.OneToOneField(TitlePost)
hello = models.CharField(max_length=100, unique=True)
def __unicode__(self):
return self.hello
为什么
TopTitlePostPage
和NewTitlePostPage
不继承TitlePost
中的所有属性?例如,如果我尝试在模板中使用TopTitlesPostPage
调用likes
,它将不会执行,因为likes
属性没有继承。OneToOneField
是否与问题有关?我确实读过,制作TitlePost
一个元类会有帮助,但我需要它在我的数据库中有一个表。实际上,我希望它们在我的数据库中都有一个表。再说一遍,也许我的方法不对,我应该使用TitlePost
作为生成所有内容的模型?您需要TopTitlePostPage
和NewTitlePostPage
扩展TitlePost
的基类,就像这样
class TopTitlesPostPage(models.Model)
如果从基类继承,则不需要OneToOneField
,因为TitlePost
的属性将在子类中可用。如果您想将TitlePost
抽象化(您不能声明该类的实例,只能从该类继承),则必须将其添加到meta类中
class TitlePost(models.Model):
class Meta:
abstract = True
这里是指向的链接。您需要有
TopTitlePostPage
和NewTitlePostPage
扩展TitlePost
的基类,就像这样
class TopTitlesPostPage(models.Model)
如果从基类继承,则不需要OneToOneField
,因为TitlePost
的属性将在子类中可用。如果您想将TitlePost
抽象化(您不能声明该类的实例,只能从该类继承),则必须将其添加到meta类中
class TitlePost(models.Model):
class Meta:
abstract = True
这里是到的链接。您需要扩展类,如下所示:
class TopTitlesPostPage(TitlePost):
你只需提及所有以逗号分隔的模型,就可以添加更多的模型并从多个模型继承!这样,模型中的所有字段也将在子类中创建
编辑:
我的方法是创建一个包含所有公共字段的抽象类,并将其扩展到TitlePost、TopTitlePostPageA和NewTitlePostPage中。您需要像下面这样扩展这些类:
class TopTitlesPostPage(TitlePost):
你只需提及所有以逗号分隔的模型,就可以添加更多的模型并从多个模型继承!这样,模型中的所有字段也将在子类中创建
编辑:
我的方法是创建一个包含所有公共字段的抽象类,并将其扩展到TitlePost、topTitlePostPageA和newTitlePostPage中。您希望看到的行为称为。每个子类在内部都以您编写的相同内容结束,因此基类的TitlePost有一个一对一的字段,但它在内部由django管理 如果您像下面的代码那样执行多重继承,您将能够编写:
k=TopTitlesPostPage.objects.create(hello="Hello",title_name="Heh")
这意味着这些字段可以直接访问
from django.db import models
class TitlePost(models.Model):
title_name = models.CharField(max_length=100, unique=True)
title_body = models.TextField(max_length=30000)
title_why = models.TextField(max_length=250, null=True)
title_publication_date = models.DateTimeField('date')
likes = models.IntegerField(default=0)
dislikes = models.IntegerField(default=0)
def __unicode__(self):
return self.title_name
class TopTitlesPostPage(TitlePost):
hello = models.CharField(max_length=100, unique=True)
def __unicode__(self):
return self.hello
class NewTitlesPostPage(TitlePost):
hello = models.CharField(max_length=100, unique=True)
def __unicode__(self):
return self.hello
如果您永远不会真正引用基类TitlePost
,而只引用其子类,那么将“TitlePost:
制作TitlePost
抽象将省略数据库中表TitlePost
的创建,子模型最终将基类的字段分别插入到它们自己的表中。如果基类只是用于分解公共功能,那么这是首选方法
对于大型查询,这也会影响性能,因为ORM需要执行较少的JOIN
操作
在Django中不可能为抽象模型安装外键。
但是,您可以将外键安装到非抽象基类。唯一的限制是反向外键关系将返回基类实例。
您可以通过使用来规避此限制
Django多态允许您查询基类对象,但检索子类实例:
>>> Project.objects.create(topic="Department Party")
>>> ArtProject.objects.create(topic="Painting with Tim", artist="T. Turner")
>>> ResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter")
>>> Project.objects.all()
[ <Project: id 1, topic "Department Party">,
<ArtProject: id 2, topic "Painting with Tim", artist "T. Turner">,
<ResearchProject: id 3, topic "Swallow Aerodynamics", supervisor "Dr. Winter"> ]
外键还将返回子类实例,如果您试图实现多态性,这将非常酷
# The model holding the relation may be any kind of model, polymorphic or not
class RelatingModel(models.Model):
many2many = models.ManyToManyField('ModelA') # ManyToMany relation to a polymorphic model
>>> o=RelatingModel.objects.create()
>>> o.many2many.add(ModelA.objects.get(id=1))
>>> o.many2many.add(ModelB.objects.get(id=2))
>>> o.many2many.add(ModelC.objects.get(id=3))
>>> o.many2many.all()
[ <ModelA: id 1, field1 (CharField)>,
<ModelB: id 2, field1 (CharField), field2 (CharField)>,
<ModelC: id 3, field1 (CharField), field2 (CharField), field3 (CharField)> ]
#持有关系的模型可以是任何类型的模型,多态或非多态
类关系模型(models.Model):
many2many=models.ManyToManyField('ModelA')#与多态模型的manytomy关系
>>>o=RelatingModel.objects.create()
>>>o.many2many.add(ModelA.objects.get(id=1))
>>>o.many2many.add(ModelB.objects.get(id=2))
>>>o.many2many.add(ModelC.objects.get(id=3))
>>>o.many2many.all()
[ ,
,
]
考虑到这些查询将被调用。您希望看到的行为被调用。每个子类在内部都以您编写的相同内容结束,因此基类的TitlePost有一个一对一的字段,但它在内部由django管理 如果您像下面的代码那样执行多重继承,您将能够编写:
k=TopTitlesPostPage.objects.create(hello="Hello",title_name="Heh")
这意味着这些字段可以直接访问
from django.db import models
class TitlePost(models.Model):
title_name = models.CharField(max_length=100, unique=True)
title_body = models.TextField(max_length=30000)
title_why = models.TextField(max_length=250, null=True)
title_publication_date = models.DateTimeField('date')
likes = models.IntegerField(default=0)
dislikes = models.IntegerField(default=0)
def __unicode__(self):
return self.title_name
class TopTitlesPostPage(TitlePost):
hello = models.CharField(max_length=100, unique=True)
def __unicode__(self):
return self.hello
class NewTitlesPostPage(TitlePost):
hello = models.CharField(max_length=100, unique=True)
def __unicode__(self):
return self.hello
如果您永远不会真正引用基类TitlePost
,而只引用其子类,那么将“TitlePost:
制作TitlePost
抽象将省略数据库中表TitlePost
的创建,子模型最终将基类的字段分别插入到它们自己的表中。如果基类只是用于分解公共功能,那么这是首选方法
对于大型查询,这也会影响性能,因为ORM需要执行较少的JOIN
操作
在Django中不可能为抽象模型安装外键。
但是,您可以将外键安装到非抽象基类。唯一的限制是反向外键关系将返回基类实例。
你可以通过我们绕过这个限制