以下示例最佳描述了我要做的事情:
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
)?
答案 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方法旨在执行“表格范围”的事情,但模型方法应该作用于特定的模型实例。
如果你有一个方法在模型方法中进行过滤,那就是代码气味,它属于自定义管理器。