django 从导入的应用覆盖模型的__str__(self)

xe55xuns  于 2023-01-06  发布在  Go
关注(0)|答案(2)|浏览(136)

我面临着以下情况:我有一个django项目,它使用了一个外部应用程序[App 1]。在App 1中,它具有以下结构:
1.抽象类“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

1.基于“Base”的抽象类,称为“AbstractClassA”:

class AbstractClassA(Base):

    display_name = models.CharField(max_length=200)
    ....
    ....

    class Meta(Base.Meta):
        abstract = True

    def get_display_name(self):
        ....
        ....
        return ....

1.非抽象类类ClassA(AbstractClassA)
现在,当我在视图中查询ClassA时,例如:

qs = ClassA.objects.filter(Q(name__icontains=query_term)....)
    return qs

我把这个qs输入到另一个外部应用程序(autocomplete)中,这样当我在网页表单上输入“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' + '; qs中每个过滤项的“+”fieldB“)。
我的想法是在某个地方覆盖这个__str__方法,但由于我的流程的上游和下游都是在外部应用程序中完成的,我不想直接修改(即直接复制到我的Django项目中并重写某些部分),我不确定如何才能实现我的目标。
有什么优雅的方法可以做到这一点吗?
如果有任何不清楚的地方,或者我可以提供更多的信息,请告诉我。谢谢!

mctunoxg

mctunoxg1#

除了Monkey Patching之外的另一种方法是使用代理模型。

class MyClassA(ClassA):

    class Meta:
        proxy = True

    def __str__(self):
        return self.attribute

然后使用MyClassA代替ClassA

8yoxcaq7

8yoxcaq72#

从你的问题来看,并不清楚非抽象类是否是你写的,但是你可以做的是创建一个mixin,并将其添加到你的具体类的类签名中,比如:

class NiceStrMixin():
    def __str__(self):
        return self.display_name

那么

class ClassA(AbstractClassA, NiceStrMixin):
     ...

如果您也没有ClassA的访问权限,则可以使用monkey patchAbstractClassA

相关问题