我遇到以下情况:我有一个django项目,它使用外部应用程序[App1]。在App1中,它具有以下结构:
抽象类'基础':
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'的抽象类,名为'AbstractClassA':
class AbstractClassA(Base):
display_name = models.CharField(max_length=200)
....
....
class Meta(Base.Meta):
abstract = True
def get_display_name(self):
....
....
return ....
非抽象类class ClassA(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',在qs中显示每个过滤项目的'fieldA'+';'+'fieldB')。
我的想法是在某处覆盖这个__str__
方法。但是因为我的进程的上游和下游都在外部应用程序中完成,我不想直接修改(即直接复制到我的Django项目并重写某些部分),我不确定如何实现我的目标
有没有优雅的方法呢?
如果有任何不清楚的地方,或者我可以向您提供任何进一步的信息,请告诉我。谢谢!
答案 0 :(得分:3)
除了monkeypatching之外的另一种方法是使用Proxy models。
class MyClassA(ClassA):
class Meta:
proxy = True
def __str__(self)
return self.attribute
然后使用MyClassA
代替ClassA
。
答案 1 :(得分:2)
根据您的问题,不清楚非抽象类是否由您编写,但您可以做的是创建一个mixin并将其添加到具体类的类签名中,例如:
class NiceStrMixin():
def __str__(self):
return self.display_name
然后
class ClassA(AbstractClassA, NiceStrMixin):
...
如果您也无法访问ClassA
,则可以monkey patch AbstractClassA
。