Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用Django MTI确定子类型或将类型指定为字段?_Python_Django_Django Models - Fatal编程技术网

Python 使用Django MTI确定子类型或将类型指定为字段?

Python 使用Django MTI确定子类型或将类型指定为字段?,python,django,django-models,Python,Django,Django Models,我正在django中使用多表继承(MTI)建立一个数据模型,如下所示: class Metric(models.Model): account = models.ForeignKey(Account) date = models.DateField() value = models.FloatField() calculation_in_progress = models.BooleanField() type = models.CharField( ma

我正在django中使用多表继承(MTI)建立一个数据模型,如下所示:

class Metric(models.Model):
    account = models.ForeignKey(Account)
    date = models.DateField()
    value = models.FloatField()
    calculation_in_progress = models.BooleanField()
    type = models.CharField( max_length=20, choices= METRIC_TYPES ) # Appropriate?

    def calculate(self):
        # default calculation...

class WebMetric(Metric):
    url = models.URLField()

    def calculate(self):
        # web-specific calculation...

class TextMetric(Metric):
    text = models.TextField()

    def calculate(self):
        # text-specific calculation...
我的直觉是在基类中放置一个“type”字段,如图所示,这样我就可以知道任何度量对象属于哪个子类。要一直保持这一点是有点麻烦的,但这是可能的。但我需要这样做吗?django是否有自动处理此问题的方法

当我调用
Metric.objects.all()
时,返回的每个对象都是
Metric
的一个实例,而不是子类。因此,如果我调用
.calculate()
,我永远不会得到子类的行为

我可以在基类上编写一个函数,测试是否可以将其转换为以下任何子类型:

def determine_subtype(self):
    try:
        self.webmetric
        return WebMetric
    except WebMetric.DoesNotExist:
        pass
    # Repeat for every sub-class
但这似乎是一堆重复的代码。而且它也不能包含在选择过滤器中——只能在python空间中使用

最好的处理方法是什么

但我需要这样做吗

从来没有。从不从来没有

django是否有自动处理此问题的方法

对。这叫做“多态性”

您永远不需要知道子类。从来没有

“我的WebMetric.url和TextMetric.text属性如何?”

使用这些属性,您将做什么?定义一个做某事的方法函数。在WebMetric(使用url)和TextMetric(使用文本)中实现不同的版本。 这是正确的多态性


请阅读:

请将您的超类抽象化

不要这样做:

您想要“单表继承”

但我需要这样做吗

从来没有。从不从来没有

django是否有自动处理此问题的方法

对。这叫做“多态性”

您永远不需要知道子类。从来没有

“我的WebMetric.url和TextMetric.text属性如何?”

使用这些属性,您将做什么?定义一个做某事的方法函数。在WebMetric(使用url)和TextMetric(使用文本)中实现不同的版本。 这是正确的多态性


请阅读:

请将您的超类抽象化

不要这样做:


您想要“单表继承”。

虽然它可能会冒犯某些人的感情,但解决此问题的唯一实用方法是在基类中放置一个字段或一个方法,说明每个记录实际上是什么类型的对象。您所描述的方法的问题是,对于您正在处理的每个对象,它需要对每种类型的子类进行单独的数据库查询。在处理大型查询集时,这可能会变得非常缓慢。更好的方法是对django内容类型类使用ForeignKey

@Carl Meyer在这里写了一个很好的解决方案:


单表继承可以帮助缓解这个问题,具体取决于它的实现方式。但目前Django并不支持它:因此这不是一个有用的建议。

虽然它可能会冒犯一些人的感情,但解决这个问题的唯一实用方法是在基类中放置一个字段或一个方法,说明每个记录实际上是什么类型的对象。您所描述的方法的问题是,对于您正在处理的每个对象,它需要对每种类型的子类进行单独的数据库查询。在处理大型查询集时,这可能会变得非常缓慢。更好的方法是对django内容类型类使用ForeignKey

@Carl Meyer在这里写了一个很好的解决方案:


单表继承可以帮助缓解这个问题,具体取决于它的实现方式。但目前Django不支持这一建议:因此这不是一个有用的建议。

我不确定我是否理解您的问题。。。您的意思是,在对“Metric”执行某些操作时,例如:“a_Metric_to_recognize=Metric.objects.get(pk=some_pk)”,您希望能够识别“Metric”是“WebMetric”还是“TextMetric”??我不确定是否理解您的问题。。。你的意思是,你想在对“Metric”执行某些操作时识别“Metric”是“WebMetric”还是“TextMetric”,例如:“a_Metric_to_recognize=Metric.objects.get(pk=some_pk)”?我认为这不管用。如果调用Metric.objects.all(),它实际上会返回子类对象吗?我以为它只会返回公制对象。在第三段代码中,他们显式地将对象强制转换为其子类。我认为S.Lott的意思是,您不应该对“度量”执行任何特定于“WebMetric”或“TextMetric”的操作。定义“Metric”上需要的所有函数,在子类中重写它们,然后在“Metric”上调用它们。如果您需要明确知道对象来自哪个子类,那么您可能会遇到设计问题。操纵“度量”,因此仅操纵公共功能或其中一个子类。请详细描述你正在尝试做什么,然后我们可以帮助你的设计!洛特的想法在理论上很好,但在Django就行不通了。我刚查过。当我使用Metric.objects从数据库中提取对象时,它们会作为Metric对象返回,而不是作为子类的实例返回。所以多态性在这里实际上不起作用。如果我在基类中定义一个方法并在子类中重写它,子类的方法将不会被调用,因为我实际上没有子类的实例。避免“多表继承”。请阅读以下内容:。让你的超类抽象化。我为什么要避免MTI?因为多态性不起作用?这就是我想要的答案。抽象基类是不合适的,因为我经常希望基类没有额外的数据。抽象基类在从db中提取对象方面是相同的——我仍然需要知道clas是什么