标签: multi-table-inheritance

我应该以任何方式避免Django中的多表(具体)继承吗?

许多有经验的开发人员建议不要使用Django多表继承,因为它的性能很差:

  1. Django的疑难杂症:混凝土继承雅各布·卡普兰,莫斯,Django的一个核心因素.

    几乎在所有情况下,抽象继承是一种长期更好的方法.我看到在混凝土继承引入的负载下,有很多网站被粉碎,所以我强烈建议Django用户在大量怀疑的情况下使用具体的继承.

  2. Django中的两勺丹尼尔·格林菲尔德(@pydanny)

    多表继承,有时称为"具体继承",作者和许多其他开发人员认为这是一件坏事.我们强烈建议不要使用它.

    不惜一切代价,每个人都应该避免多表继承,因为它会增加混乱和大量开销.而不是多表继承,在模型之间使用显式OneToOneFields和ForeignKeys,以便您可以控制何时遍历连接.

但是没有多表继承,我不能轻易

  1. 另一个模型中的参考基础模型(必须使用GenericForeignKey或反向依赖);

  2. 获取基本模型的所有实例.

    (随意添加更多)

那么Django中这种继承有什么问题?为什么明确的OneToOneField更好?

性能对JOIN的影响有多大?有没有显示性能差异的基准测试?

不会select_related()让我们连接被调用时控制?


我已经将具体示例移到了一个单独的问题,因为这个问题变得过于宽泛,并且添加了使用多表继承的原因列表.

django inheritance models concrete-inheritance multi-table-inheritance

40
推荐指数
4
解决办法
7026
查看次数

Django 1.9:Field与父模型中不存在的字段的字段冲突

我有一些简单的模型,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'.这是一个错误还是我错过了什么?同样的事情发生在另一个项目中.

django name-clash multi-table-inheritance django-1.9

23
推荐指数
2
解决办法
7686
查看次数

has_one through和多表继​​承的多态关联

在我目前正在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).但有些事阻止了我:

  • 它没有开箱即用
  • 对于像我这样的新手来说,MTI看起来很难实现
  • 实施解决方案的宝石似乎过时了,太复杂或不完整
  • 宝石可能会在rails4下破坏,因为它们暂时没有更新

所以我寻找另一种解决方案,我发现了多态关联.

我从昨天起就开始使用它并花了一些时间使其工作,即使在Rails多态性has_many的帮助下:通过ActiveRecord,has_many:through和多态关联

我设法从上面的问题做了例子,但是花了一段时间,我终于遇到了两个问题:

  1. 如何将用户关系转换为has_one关联,并能够"盲目"访问链接实体?
  2. 如何设置约束,以便没有用户可以拥有多个实体?
  3. 有没有更好的方法来做我想要的?

activerecord ruby-on-rails polymorphic-associations multi-table-inheritance

12
推荐指数
1
解决办法
6539
查看次数

具有多表继承的父类的Django post_save信号

在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接收函数被调用?

django django-models multi-table-inheritance

5
推荐指数
2
解决办法
2304
查看次数

Django 将`choices` 添加到继承的模型字段

使用多表继承,我有两个模型:

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

5
推荐指数
1
解决办法
1321
查看次数

保存在 django 中后,对象的 id 为 None

我正在循环遍历对象列表并保存。我需要保存后新生成的 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

5
推荐指数
1
解决办法
5960
查看次数

将Django模型父类添加到现有模型中以实现多表继承

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 models multi-table-inheritance

5
推荐指数
1
解决办法
2783
查看次数