django的多态模型实现

django-polymodels的Python项目详细描述


一个django应用程序,它提供了一种简单的方法来检索类型为casted的模型 到他们原来的ContentType

https://travis-ci.org/charettes/django-polymodels.svg?branch=masterhttps://coveralls.io/repos/charettes/django-polymodels/badge.svg?branch=master&service=github

安装

>>> pip install django-polymodels

确保'django.contrib.contenttypes''polymodels'在 您安装的应用程序

INSTALLED_APPS += ('django.contrib.contenttypes', 'polymodels')

用法

子类PolymorphicModel,一个抽象模型类。

from django.db import models
from polymodels.models import PolymorphicModel

class Animal(PolymorphicModel):
    name = models.CharField(max_length=255)

    def __unicode__(self):
        return self.name

class Mammal(Animal):
    pass

class Dog(Mammal):
    pass

class Reptile(Animal):
    pass

class Snake(Reptile):
    class Meta:
        proxy = True

对象的创建方式与通常相同,并且它们的关联ContentType 自动保存:

>>> animal = Animal.objects.create(name='animal')
>>> mammal = Mammal.objects.create(name='mammal')
>>> reptile = Reptile.objects.create(name='reptile')
>>> snake = Snake.objects.create(name='snake')

要从Animal.objectsmanager中检索type casted实例,您只需 必须使用select_subclasses方法。

>>> Animal.objects.select_subclasses()
[<Animal: animal>, <Mammal: mammal>, <Reptile: reptile>, <Snake: snake>]

还可以通过将子类的子集作为参数传递给 select_subclass

>>> Animal.objects.select_subclasses(Reptile)
[<Reptile: reptile>, <Snake: snake>]

或者直接从子类管理器。

>>> Reptile.objects.select_subclasses(Snake)
[<Snake: snake>]

注意,您还可以通过避免 select_subclasses调用。

>>> Animal.objects.all()
[<Animal: animal>, <Animal: mammal>, <Animal: reptile>, <Animal: snake>]

也可以只选择模型的实例 使用exclude_subclasses方法附加管理器。

>>> Mammal.objects.all()
[<Mammal: mammal>]

PolymorphicModel的每个实例都有一个type_cast方法,该方法知道如何 将自身转换为正确的ContentType

>>> animal_snake = Animal.objects.get(pk=snake.pk)
<Animal: snake>
>>> animal_snake.type_cast()
<Snake: snake>
>>> animal_snake.type_cast(Reptile)
<Reptile: snake>

如果PolymorphicModel.content_type字段与 只需子类的现有字段 polymodels.models.BasePolymorphicModel并指定哪个字段polymodels 应该通过在模型上定义CONTENT_TYPE_FIELD属性来代替。 此字段必须是ForeignKeyContentType

from django.contrib.contenttypes.models import ContentType
from django.db import models
from polymodels.models import BasePolymorphicModel

class MyModel(BasePolymorphicModel):
    CONTENT_TYPE_FIELD = 'polymorphic_ct'
    polymorphic_ct = models.ForeignKey(ContentType)

工作原理

在引擎盖下select_subclasses调用seleted_related以避免 不必要的查询和filter如果您传递一些类给它。在奎丽斯特 迭代,通过调用 BasePolymorphicModel.type_cast。注意,这些查找是在类上缓存的 创建以避免在每个查询上计算它们。

作者注释

我知道已经有很多现有的项目来解决整个问题。 模型继承类型转换事物例如django-polymorphic。然而 我想以轻量级的方式实现这个特性:不 __metaclass____init__在使用django的公共api作为 尽可能多。最后,这真的只是 django-mutant因为我需要它作为 另一个项目的独立应用程序。

贡献

如果您碰巧遇到了一个bug或者希望建议添加一个特性 请file an issuecreate a pull request包含测试

学分

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
ws-consumer服务地址中的java动态属性   java如何比较整数列表,然后按升序排序?   javascript我正在使用java脚本调用一个函数,但它没有调用代码下面的方法,也没有调用secretitnames()函数   在文本窗格中多次使用Java insertIcon图标   JavaMSAL安卓。AuthenticationActivity完成,但用于身份验证请求的线程池线程仍处于等待状态   if语句中的java多范围比较   java toString()表示输出   java如何在jcstrest测试中生成指令重新排序   java我怎样才能运行它?   web应用程序中使用Hibernate和Spring的java问题   如何将字符串数据写入Java文本文件   如何在java命令提示符下运行已签名的jar文件?   java从我的菜单调用RCP应用程序   java如何等待Canvas/GraphicsContext完成任务,然后再继续执行代码块?