Django - 在抽象方法中获取原始 class 名称
Django - getting the original class name in abstact method
以下示例最能说明我正在尝试做的事情:
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 处理调用 class(即 InheritedClass
)?
你可以做到 self.objects.filter(...).update(..)
抽象 class 只是实现由其具体 class 继承的方法,此处 InheritedClass
。因此,方法和字段的所有内容都可以在继承 class 中使用。
但是,对于这种情况,我建议您考虑制作自定义模型管理器。模型中的方法旨在处理该特定行的字段,而管理器旨在工作 table-wide,如 model methods
中所述
Define custom methods on a model to add custom “row-level” functionality to your objects. Whereas Manager methods are intended to do “table-wide” things, model methods should act on a particular model instance.
如果您有一个方法在模型方法中进行过滤,那是一种代码味道,它属于自定义管理器。
技术回答:嗯,很简单,是的:
def abstract_method(self):
type(self).objects.filter(..).update(....)
return self
请注意,这是 Python 方法是使用 "calling" 对象(调用该方法的对象)作为第一个参数调用的,所有属性查找都将在此对象上进行,它是class - 否则继承根本行不通。这里唯一特定于 Django 的部分是 Django 阻止您在模型实例上使用 ModelManager,因此您需要明确获取对象的 class,它由 type(self)
.
返回
但是:
编码风格注意事项
Django 建议作用于整个 table 的模型方法应该属于 ModelManager(与仅作用于当前行的方法形成对比,这些方法将作为普通方法实现),因此显然您的方法整体上 table 它 可能 作为 ModelManager 方法更好。
我说 "might" 因为有一个灰色区域,其中更新一行意味着也更新其他一些行 - 一个典型的例子是当你有一个应该总是只为一个记录设置的标志时,所以你还想在所有其他记录上取消设置。您的问题中(当然)没有足够的上下文来判断哪个是正确的选择。
以下示例最能说明我正在尝试做的事情:
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 处理调用 class(即 InheritedClass
)?
你可以做到 self.objects.filter(...).update(..)
抽象 class 只是实现由其具体 class 继承的方法,此处 InheritedClass
。因此,方法和字段的所有内容都可以在继承 class 中使用。
但是,对于这种情况,我建议您考虑制作自定义模型管理器。模型中的方法旨在处理该特定行的字段,而管理器旨在工作 table-wide,如 model methods
中所述Define custom methods on a model to add custom “row-level” functionality to your objects. Whereas Manager methods are intended to do “table-wide” things, model methods should act on a particular model instance.
如果您有一个方法在模型方法中进行过滤,那是一种代码味道,它属于自定义管理器。
技术回答:嗯,很简单,是的:
def abstract_method(self):
type(self).objects.filter(..).update(....)
return self
请注意,这是 Python 方法是使用 "calling" 对象(调用该方法的对象)作为第一个参数调用的,所有属性查找都将在此对象上进行,它是class - 否则继承根本行不通。这里唯一特定于 Django 的部分是 Django 阻止您在模型实例上使用 ModelManager,因此您需要明确获取对象的 class,它由 type(self)
.
但是:
编码风格注意事项
Django 建议作用于整个 table 的模型方法应该属于 ModelManager(与仅作用于当前行的方法形成对比,这些方法将作为普通方法实现),因此显然您的方法整体上 table 它 可能 作为 ModelManager 方法更好。
我说 "might" 因为有一个灰色区域,其中更新一行意味着也更新其他一些行 - 一个典型的例子是当你有一个应该总是只为一个记录设置的标志时,所以你还想在所有其他记录上取消设置。您的问题中(当然)没有足够的上下文来判断哪个是正确的选择。