Django:铸造抽象模型

2024-04-20 09:54:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个抽象的Django模型,我用它来创建另外两个模型。在处理下面的不同示例时,如何避免重复代码(例如,在创建盒装谷物和Bowled谷物时,我希望避免重复函数两次。你知道吗

class Cereal(models.Model):
    name = models.CharField()
    class Meta:
        abstract = True

class Boxed(Cereal):
    pass

class Bowled(Cereal):
    pass


func some_func_boxed(name):
    boxed = Boxed.objects.get(id=1)
    boxed.name = name
    boxed.save()

func some_func_bowled(name):
    bowled = Bowled.objects.get(id=1)
    bowled.name = name
    bowled.save()

Tags: name模型getobjectsmodelssomepassclass
3条回答

您可以将其添加为@classmethod模型上的Cereal

class Cereal(models.Model):
    name = models.CharField()

    @classmethod
    def some_func_cereal(cls, name):
        bowled = cls.objects.get(id=1)
        bowled.name = name
        bowled.save()

    class Meta:
        abstract = True

然后,可以使用以下方法调用此方法:

Boxed.some_func_cereal('Captain Crunch')
Bowled.some_func_cereal('Lucky Charms')

调用class方法的类在some_func_cereal函数中作为cls参数传递。你知道吗

def some_func(name, Instance):
    i = Instance.objects.get(id=1)
    i.name = "some name"
    i.save()

好主意是使用strategy pattern,例如:https://medium.com/@sheikhsajid/design-patterns-in-python-part-1-the-strategy-pattern-54b24897233e

您可以将update方法添加到abstract类中,例如:

    class Cereal:

        def update(self, **kwargs):
            for key, val in kwargs.items():
                setattr(self, key, val)
            self.save(update_fields=kwargs.keys())
            return self

并按如下方式使用它来更新您喜欢的任何列

    BoxedInstance.update(name="new name")

    or 

    BoxedInstance.update(name="new name", taste="cardboardy")

相关问题 更多 >