从基类创建Django代理模型的实例 [英] Creating instances of Django proxy models from their base class

查看:112
本文介绍了从基类创建Django代理模型的实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一系列如下所示的模型:

I have a series of models that look like this:

class Analysis(models.Model):
    analysis_type = models.CharField(max_length=255)

    def important_method(self):
        ...do stuff...


class SpecialAnalysis(Analysis):
    class Meta:
        proxy = True

    def important_method(self):
        ...something different...

这都是非常标准的。但是,我想做的就是根据 analysis_type Analysis 模型转换为代理模型。 c>字段。例如,我希望能够编写如下代码:

This is all pretty standard. However, what I'd like to do is automatically convert an Analysis model to a proxy model based on the value of the analysis_type field. For example, I'd like to be able to write code that looks like this:

>>> analysis = Analysis.objects.create(analysis_type="nothing_special")
>>> analysis.__class__
<class 'my_app.models.Analysis'>

>>> analysis = Analysis.objects.create(analysis_type="special")
>>> analysis.__class__
<class 'my_app.models.SpecialAnalysis'>

>>> analysis = Analysis.objects.get(pk=2)
>>> analysis.__class__
<class 'my_app.models.SpecialAnalysis'>

>>> # calls the ``important_method`` of the correct model
>>> for analysis in Analysis.objects.all():
...     analysis.important_method()

这是否遥不可及?有人问了类似的问题此处,实际上为迭代示例提供了一些代码,但仍然让我面临如何从父类获取或创建代理类实例的问题。我想我可以重写一堆管理器方法,但是我觉得必须有一种更优雅的方法。

Is this even remotely possible? A similar question was asked here, which actually gives some code for the iteration example, but it still leaves me with the question of how to get or create an instance of a proxy class from its parent. I suppose I could just override a bunch of manager methods, but I feel like there must be a more elegant way to do it.

推荐答案

<我还没有找到一种干净或优雅的方式来做到这一点。当我遇到这个问题时,我通过欺骗Python来解决了这个问题。

I haven't found a "clean" or "elegant" way to do this. When I ran into this problem I solved it by cheating Python a little bit.

class Check(models.Model):
    check_type = models.CharField(max_length=10, editable=False)
    type = models.CharField(max_length=10, null=True, choices=TYPES)
    method = models.CharField(max_length=25, choices=METHODS)
    'More fields.'

    def __init__(self, *args, **kwargs):
        super(Check, self).__init__(*args, **kwargs)
        if self.check_type:
            map = {'TypeA': Check_A,
                'TypeB': Check_B,
                'TypeC': Check_C}
            self.__class__ = map.get(self.check_type, Check)

    def run(self):
        'Do the normal stuff'
        pass


class Check_A(Check):
    class Meta:
        proxy = True

    def run(self):
        'Do something different'
        pass

class Check_B(Check):
    class Meta:
        proxy = True

    def run(self):
        'Do something different'
        pass


class Check_C(Check):
    class Meta:
        proxy = True

    def run(self):
        'Do something different'
        pass

这不是很干净,但是这是找到解决我问题的最简单的方法。

It's not really clean but it was the easiest hack to find which solved my problem.

也许这对您有帮助,也许没有用。

Maybe this is helps you, maybe it doesn't.

我也希望其他人对这个问题有更多的Python解决方案,因为我正在计算直到这种方法失败并再次困扰我的日子。

I'm also hoping someone else has a more pythonic solution to this problem since I'm counting the days till this method fails and comes back to haunt me..

这篇关于从基类创建Django代理模型的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆