首页 > 解决方案 > django中的固有python抽象基类

问题描述

我想在 python 中创建一个通用模块,它使用来自 Django 模型的数据,并使用类型来记录接口。该模块应该独立于 Django 模型。这应该如何以pythonic方式完成?

我正在考虑使用 ABC 类,独立的 python 文件应该类似于(shape.py):

from abc import ABC


class Shape(ABC):
    @property
    @abstractmethod
    def height(self) -> float:
         pass

    @property
    @abstractmethod
    def area(self) -> float:
         pass


class VolumeCalculation:
    def __init__(self, shape: Shape) -> None:
        self.shape = shape

    def volume(self) -> float
        return self.shape.area*self.shape.height

虽然 django 模型是在另一个文件中定义的:

from django.db import models
from shape import Shape


class Box(models.Model, Shape):
    height= models.FloatField('height')
    area = models.FloatField('area')

当我这样做时,我收到以下错误:

TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

或者,我可以删除基类并使用 Shape 中所需的参数构造 VolumeCalculation。但是由于真实对象包含许多参数,因此列表变得很长。

标签: pythondjangodesign-patterns

解决方案


您不必派生BoxShape使其成为 a Shape,您只需注册它

from django.db import models
from shape import Shape


class Box(models.Model):
    height= models.FloatField('height')
    area = models.FloatField('area')

Shape.register(Box)

推荐阅读