Skip to content

Commit

Permalink
feat: 增加多态模型基类
Browse files Browse the repository at this point in the history
  • Loading branch information
Guo-Zhang committed Aug 23, 2023
1 parent b2252f0 commit 9e3f269
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 66 deletions.
8 changes: 3 additions & 5 deletions django_quanttide/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@
CreatedAtField, UpdatedAtField,
CreatedByField, UpdatedByField,
)
from .models import Model, PolymorphicModel

from .models import Model
from .polymorphic import PolymorphicModel

__all__ = [
'Model',
'PolymorphicModel',
'IDField',
'Model', 'IDField',
'NumberField',
'NameField',
'VerboseNameField',
Expand Down
52 changes: 1 addition & 51 deletions django_quanttide/models/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@

from django.db import models

from polymorphic.models import PolymorphicModel as BasePolymorphicModel

from .fields import IDField, CreatedAtField, UpdatedAtField
from .fields import IDField


class Model(models.Model):
Expand All @@ -19,51 +17,3 @@ class Model(models.Model):

class Meta:
abstract = True


class PolymorphicModel(BasePolymorphicModel):
"""
多态数据模型
类型字段映射表(TYPE_FIELD_MAPPINGS)是一个键值对字典,用于将模型名称(即 ContentType 表的 model 值)映射到用户定义的类型值。
如果需要使用类型字段映射表,请在子类中覆盖 TYPE_FIELD_MAPPINGS 属性。
示例:
```
class Project(PolymorphicModel):
TYPE_FIELD_MAPPINGS = {
# 项目
'Project': 'default',
# 项目集
'Program': 'program',
# 项目组合
'ProjectPortfolio': 'project_portfolio',
}
```
"""
id = IDField()
created_at = CreatedAtField()
updated_at = UpdatedAtField()

# 类型字段映射表
TYPE_FIELD_MAPPINGS = None

class Meta:
abstract = True

@property
def type(self) -> str:
"""
类型字段
该属性返回多态模型的类型值。如果需要使用类型字段映射表,请在子类中覆盖 TYPE_FIELD_MAPPINGS 属性。
:return: 类型值
"""
# 类名转小写,方便和ContentType.model字段对应
if self.TYPE_FIELD_MAPPINGS:
convert_mappings = {key.lower(): value for key, value in self.TYPE_FIELD_MAPPINGS.items()}
return convert_mappings[self.polymorphic_ctype.model]
else:
return self.polymorphic_ctype.model
35 changes: 35 additions & 0 deletions django_quanttide/models/polymorphic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from polymorphic.models import PolymorphicModel as BasePolymorphicModel

from django_quanttide.models import IDField, CreatedAtField, UpdatedAtField


class PolymorphicModel(BasePolymorphicModel):
"""
多态数据模型
类型字段映射表(TYPE_FIELD_MAPPINGS)是一个键值对字典,用于将模型名称(即 ContentType 表的 model 值)映射到用户定义的类型值。
如果需要使用类型字段映射表,请在子类中覆盖 TYPE_FIELD_MAPPINGS 属性。
示例:
```
class Project(PolymorphicModel):
pass
```
"""
id = IDField()

class Meta:
abstract = True

@property
def type(self) -> str:
"""
类型字段
默认返回值为模型名称的小写形式,比如`parentmodel`、`childmodel`。
:return: 类型值
"""
# 类名转小写,方便和ContentType.model字段对应
return self.polymorphic_ctype.model
Empty file.
5 changes: 5 additions & 0 deletions django_quanttide/serializers/polymorphic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from rest_polymorphic.serializers import PolymorphicSerializer as BasePolymorphicSerializer


class PolymorphicSerializer(BasePolymorphicSerializer):
pass
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ packages = [{include = "django_quanttide"}]
python = "^3.8"
Django = ">=3.1"
djangorestframework = ">=3.0"

[tool.poetry.dependencies.polymorphic]
django-polymorphic = "^3.1.0"
django-rest-polymorphic = "^0.1.10"

[tool.poetry.group.dev.dependencies]
pytest = "^7.3.2"
Expand Down
19 changes: 13 additions & 6 deletions tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,19 @@ class Meta:
verbose_name_plural = '示例模型列表'


class ExamplePolymorphicModel(models.PolymorphicModel):
TYPE_FIELD_MAPPINGS = {
'ExamplePolymorphicModel': 'default',
'ChildModel': 'child_model'
}
class BaseParentModel(models.PolymorphicModel):
class Meta:
abstract = True


class BaseChildModel(models.PolymorphicModel):
class Meta:
abstract = True


class ParentModel(BaseParentModel):
pass


class ChildModel(ExamplePolymorphicModel):
class ChildModel(ParentModel):
pass
8 changes: 4 additions & 4 deletions tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from tests.models import (
ExampleModel,
ExamplePolymorphicModel, ChildModel
ParentModel, ChildModel
)


Expand Down Expand Up @@ -57,13 +57,13 @@ def test_updated_at(self):

class PolymorphicModelTestCase(TestCase):
def setUp(self):
self.instance = ExamplePolymorphicModel.objects.create()
self.instance = ParentModel.objects.create()
self.child_instance = ChildModel.objects.create()

def test_default_type(self):
# Test that the default type is returned when polymorphic_ctype is None
self.assertEqual('default', self.instance.type)
self.assertEqual('parentmodel', self.instance.type)

def test_child_model_type(self):
print(self.child_instance.__class__.__name__)
self.assertEqual('child_model', self.child_instance.type)
self.assertEqual('childmodel', self.child_instance.type)

0 comments on commit 9e3f269

Please sign in to comment.