从导入的应用程序覆盖模型的 __str__(self)
override __str__(self) of a model from an imported app
我面临以下情况:我有一个 django 项目,它使用外部应用程序 [App1]。在 App1 中,它具有以下结构:
摘要class'Base':
class Base(models.Model):
"""
Base model with boilerplate for all models.
"""
name = models.CharField(max_length=200, db_index=True)
alternate_names = models.TextField(null=True, blank=True,
default='')
..............
..............
class Meta:
abstract = True
def __str__(self):
display_name = getattr(self, 'display_name', None)
if display_name:
return display_name
return self.name
基于'Base'抽象class,称为'AbstractClassA':
class AbstractClassA(Base):
display_name = models.CharField(max_length=200)
....
....
class Meta(Base.Meta):
abstract = True
def get_display_name(self):
....
....
return ....
非抽象classclassClassA(AbstractClassA)
现在,当我在我的视图中对此 ClassA 进行查询时,例如:
qs = ClassA.objects.filter(Q(name__icontains=query_term)....)
return qs
我将这个 qs 提供给另一个外部应用程序(自动完成),这样当我在我的网络表单上输入 'xxxx' 时,该表单会根据这个 qs 给我关于数据库中可用匹配项的建议.
这一切都很好,唯一的问题是,向我显示的潜在匹配列表是 ClassA 对象的默认表示,我追溯到
def __str__(self):
display_name = getattr(self, 'display_name', None)
if display_name:
return display_name
return self.name
在我之前提到的基本抽象模型中定义。我想要的是,将其他内容显示为潜在匹配列表(例如,而不是 'display_name' 或 'name',显示 'fieldA' + ';'+ 'fieldB' qs 中的每个过滤项目)。
我的想法是在某处覆盖此 __str__
方法。但是因为我的过程的上游和下游方面都是在我不想直接修改的外部应用程序中完成的(即直接复制到我的 Django 项目并重写某些部分),我不确定如何实现我的目标.
有什么优雅的方法吗?
如果有任何不清楚的地方,或者我可以为您提供任何进一步的信息,请告诉我。谢谢!
根据你的问题,不清楚非抽象 classes 是否是由你编写的,但你可以做的是创建一个 mixin 并将其添加到 class 的签名中您的具体 classes,例如:
class NiceStrMixin():
def __str__(self):
return self.display_name
然后
class ClassA(AbstractClassA, NiceStrMixin):
...
如果您也无法访问 ClassA
,您可以 monkey patch AbstractClassA
。
除了 monkeypatching 之外的另一种方法是使用 Proxy models.
class MyClassA(ClassA):
class Meta:
proxy = True
def __str__(self)
return self.attribute
然后使用 MyClassA
而不是 ClassA
。
我面临以下情况:我有一个 django 项目,它使用外部应用程序 [App1]。在 App1 中,它具有以下结构:
摘要class'Base':
class Base(models.Model): """ Base model with boilerplate for all models. """ name = models.CharField(max_length=200, db_index=True) alternate_names = models.TextField(null=True, blank=True, default='') .............. .............. class Meta: abstract = True def __str__(self): display_name = getattr(self, 'display_name', None) if display_name: return display_name return self.name
基于'Base'抽象class,称为'AbstractClassA':
class AbstractClassA(Base): display_name = models.CharField(max_length=200) .... .... class Meta(Base.Meta): abstract = True def get_display_name(self): .... .... return ....
非抽象classclassClassA(AbstractClassA)
现在,当我在我的视图中对此 ClassA 进行查询时,例如:
qs = ClassA.objects.filter(Q(name__icontains=query_term)....)
return qs
我将这个 qs 提供给另一个外部应用程序(自动完成),这样当我在我的网络表单上输入 'xxxx' 时,该表单会根据这个 qs 给我关于数据库中可用匹配项的建议.
这一切都很好,唯一的问题是,向我显示的潜在匹配列表是 ClassA 对象的默认表示,我追溯到
def __str__(self):
display_name = getattr(self, 'display_name', None)
if display_name:
return display_name
return self.name
在我之前提到的基本抽象模型中定义。我想要的是,将其他内容显示为潜在匹配列表(例如,而不是 'display_name' 或 'name',显示 'fieldA' + ';'+ 'fieldB' qs 中的每个过滤项目)。
我的想法是在某处覆盖此 __str__
方法。但是因为我的过程的上游和下游方面都是在我不想直接修改的外部应用程序中完成的(即直接复制到我的 Django 项目并重写某些部分),我不确定如何实现我的目标.
有什么优雅的方法吗?
如果有任何不清楚的地方,或者我可以为您提供任何进一步的信息,请告诉我。谢谢!
根据你的问题,不清楚非抽象 classes 是否是由你编写的,但你可以做的是创建一个 mixin 并将其添加到 class 的签名中您的具体 classes,例如:
class NiceStrMixin():
def __str__(self):
return self.display_name
然后
class ClassA(AbstractClassA, NiceStrMixin):
...
如果您也无法访问 ClassA
,您可以 monkey patch AbstractClassA
。
除了 monkeypatching 之外的另一种方法是使用 Proxy models.
class MyClassA(ClassA):
class Meta:
proxy = True
def __str__(self)
return self.attribute
然后使用 MyClassA
而不是 ClassA
。