Django - 在abstact方法中获取原始类名

时间:2018-05-16 10:59:47

标签: django django-orm

以下示例最佳描述了我要做的事情:

class MyAbstractClass(models.Model):
    abstract_field = IntegerField()

    class Meta:
        abstract = True

    def abstract_method(self):
         # THE ISSUE LIES IN THE LINE BELOW 
         ParentClass.objects.filter(..).update(....)
         return self

class InheritedClass(MyAbstractClass):
     # Field

def my_view(request):
    obj = InheritedClass.objects.get(id=1)
    obj.save()
    return obj

基本上,问题是,abstract_method中是否有任何方法告诉Django解决调用类(即InheritedClass)?

2 个答案:

答案 0 :(得分:1)

技术答案:嗯,很简单就是:

def abstract_method(self):
     type(self).objects.filter(..).update(....)
     return self

请注意,这是使用"调用"调用Python方法。 object(调用该方法的对象)作为第一个参数,所有属性查找都将发生在这个对象和它的类上 - 否则继承根本就不起作用。这里唯一的django特定部分是Django阻止您在模型实例上使用ModelManager,因此您需要明确地获取由type(self)返回的对象类。

但是:

编码样式注意事项

Django建议作用于整个表的模型方法应该属于ModelManager(与仅作用于当前行的方法相比,它们将作为普通方法实现),因此,因为你的方法明显地作用于整个表,所以可能更适合作为ModelManager方法。

我说"可能"因为有一个灰色区域,更新一行意味着更新其他一些行 - 一个典型的例子就是当你有一个标志应该总是只为一个记录设置,所以你也想在所有其他记录上取消它。当然,你的问题中没有足够的背景来说明哪个是正确的选择。

答案 1 :(得分:-1)

你可以self.objects.filter(...).update(..)

抽象类只实现由其具体类继承的方法,此处为InheritedClass。因此,继承类中可以使用方法和字段的所有内容。

但是,对于这个例子,我建议你看一下自定义模型管理器。模型中的方法旨在与特定行的字段一起使用,而管理员则按照model methods

中的描述在表格范围内工作。
  

在模型上定义自定义方法,为对象添加自定义“行级”功能。虽然Manager方法旨在执行“表格范围”的事情,但模型方法应该作用于特定的模型实例。

如果你有一个方法在模型方法中进行过滤,那就是代码气味,它属于自定义管理器。