许多有经验的开发人员建议不要使用Django多表继承,因为它的性能很差:
Django的疑难杂症:混凝土继承由雅各布·卡普兰,莫斯,Django的一个核心因素.
几乎在所有情况下,抽象继承是一种长期更好的方法.我看到在混凝土继承引入的负载下,有很多网站被粉碎,所以我强烈建议Django用户在大量怀疑的情况下使用具体的继承.
Django中的两勺由丹尼尔·格林菲尔德(@pydanny)
多表继承,有时称为"具体继承",作者和许多其他开发人员认为这是一件坏事.我们强烈建议不要使用它.
不惜一切代价,每个人都应该避免多表继承,因为它会增加混乱和大量开销.而不是多表继承,在模型之间使用显式OneToOneFields和ForeignKeys,以便您可以控制何时遍历连接.
但是没有多表继承,我不能轻易
另一个模型中的参考基础模型(必须使用GenericForeignKey或反向依赖);
(随意添加更多)
那么Django中这种继承有什么问题?为什么明确的OneToOneField更好?
性能对JOIN的影响有多大?有没有显示性能差异的基准测试?
不会select_related()让我们连接被调用时控制?
django inheritance models concrete-inheritance multi-table-inheritance
我有一些简单的模型,Profile,Certifier和Designer,后者继承自Profile(多表继承).在Designer中,有一个Certifier的外键.
class Profile(models.Model):
TYPES = (
('admin', _('Administrator')),
('certifier', _('Certifier')),
('designer', _('Designer'))
)
user = models.OneToOneField(User)
type = models.CharField(max_length=9, choices=TYPES)
def __str__(self):
return self.user.username + ' (' + self.type + ')'
class Admin(Profile):
pass
class Certifier(Profile):
pass
class Designer(Profile):
certifier = models.ForeignKey(Certifier)
Run Code Online (Sandbox Code Playgroud)
在Django 1.8中,这很有效,但在1.9中我得到了;
django.core.management.base.SystemCheckError:SystemCheckError:系统检查发现了一些问题:
错误:
check.Designer.certifier :( models.E006)字段'certifier'与模型'check.profile'中的字段'certifier'冲突.
(在这种情况下,Profile.type是无关紧要的,我只需要它来区分登录的用户配置文件类型).
check.profile显然没有字段'certifier'.这是一个错误还是我错过了什么?同样的事情发生在另一个项目中.
在我目前正在rails 4.0.0beta1下开发的项目中,我需要基于用户的身份验证,其中每个用户都可以链接到一个实体.我对铁路有点新手并且遇到了一些麻烦.
该模型如下:
class User < ActiveRecord::Base
end
class Agency < ActiveRecord::Base
end
class Client < ActiveRecord::Base
belongs_to :agency
end
Run Code Online (Sandbox Code Playgroud)
我需要的是用户能够链接到代理商或客户端,但不能同时链接到两者(这两个是我将要调用的实体).它根本没有链接,最多只有一个链接.
我首先要寻找的是如何在rails中进行Mutli-Table继承(MTI).但有些事阻止了我:
所以我寻找另一种解决方案,我发现了多态关联.
我从昨天起就开始使用它并花了一些时间使其工作,即使在Rails多态性has_many的帮助下:通过和ActiveRecord,has_many:through和多态关联
我设法从上面的问题做了例子,但是花了一段时间,我终于遇到了两个问题:
activerecord ruby-on-rails polymorphic-associations multi-table-inheritance
在Django中,如果您有使用多表继承的模型,并且您在父类上为post_save信号定义了一个接收器,那么在保存子类的实例时是否会调用该接收函数?
借用另一个问题的例子:
class Animal(models.Model):
category = models.CharField(max_length=20)
class Dog(Animal):
color = models.CharField(max_length=10)
def echo_category(sender, **kwargs):
print "category: '%s'" % kwargs['instance'].category
post_save.connect(echo_category, sender=Animal)
Run Code Online (Sandbox Code Playgroud)
如果我做:
>>> dog = Dog.objects.get(...)
>>> dog.category = "canine"
>>> dog.save()
Run Code Online (Sandbox Code Playgroud)
将echo_category接收函数被调用?
使用多表继承,我有两个模型:
class Bird(models.Model):
color = models.CharField()
class Bluebird(Bird):
...
Run Code Online (Sandbox Code Playgroud)
使用这些模型,我可以做到这一点:
birds = Bird.objects.all()
for bird in birds:
print bird.color
Run Code Online (Sandbox Code Playgroud)
这非常简单,但我不喜欢在某些情况下允许人们定义任意颜色值。例如,我想阻止用户创建Bluebird颜色字段设置为任何东西的对象,"blue"或者,在更罕见的情况下,"grey"或者"brown"。换句话说,我想在模型内的choices继承color字段上设置kwarg Bluebird。从粗略的互联网搜索来看,Django 目前似乎不允许模型子类覆盖父类的字段。
如何color在子类中定义可接受的选择的同时保留对父类中的字段的访问权限?
编辑:这个问题的重点是 Django < 1.8。在 1.8 中,添加了为字段的choiceskwarg传递可调用的功能,虽然这很好,但我正在处理尚未升级的系统,升级目前不是一种选择。
django inheritance overriding django-models multi-table-inheritance
我正在循环遍历对象列表并保存。我需要保存后新生成的 id 或指针 id,但它是 None。
这是我的代码:
for category in category_list:
saved_category = category.save()
print saved_category.parentCategory_ptr_id
print saved_category.id
Run Code Online (Sandbox Code Playgroud)
这会在例程运行后保存我的对象,但同样不会在这一行给我 id。
这是我的模型:
class ParentCategory(models.Model):
name = models.CharField(max_length=255)
class Category(ParentCategory):
description = models.CharField(max_length=255)
Run Code Online (Sandbox Code Playgroud)
类别列表的创建方式如下:
category_list = []
for row in value_list:
category = Category(description=row.description)
category_list.append(category)
return category_list
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
django django-models django-orm django-inheritance multi-table-inheritance
Django文档使用此示例来演示多表继承:
from django.db import models
class Place(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)
class Restaurant(Place):
serves_hot_dogs = models.BooleanField(default=False)
serves_pizza = models.BooleanField(default=False)
Run Code Online (Sandbox Code Playgroud)
如果我最初像这样构建 Restaurant 类:
class Restaurant(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)
serves_hot_dogs = models.BooleanField(default=False)
serves_pizza = models.BooleanField(default=False)
Run Code Online (Sandbox Code Playgroud)
然后在创建了一堆 Restaurant 对象之后,我意识到使用 MTI 会更好,有没有一种好的方法可以在事后创建父 Place 类并迁移数据?
django ×6
inheritance ×2
models ×2
activerecord ×1
django-1.9 ×1
django-orm ×1
name-clash ×1
overriding ×1