【问题标题】:How can I make a decorator in models.py?如何在 models.py 中制作装饰器?
【发布时间】:2022-01-20 15:41:40
【问题描述】:

我的 django 模型中有一个足球队课程。我做了 3 种赢、平和输的方法,self.Points_of_the_season 将被相应地修改(+3 表示胜利,+1 表示平局,+0 表示失败)。但是当我编写这些方法时,我必须在每次调用这 3 个方法时更改 self.Match_Played。如何制作一个名为 @play_match 的装饰器,它将为相关字段添加 1?

这是models.py的代码:

class Team(models.Model):
    Team_name = models.CharField(max_length=255)
    Foundation_year = models.IntegerField()
    Points_of_season = models.IntegerField(default=0)
    Match_Played = models.IntegerField(default=0)
    League = models.ForeignKey(League, on_delete=models.CASCADE)

    def __str__(self):
        return f"{self.Team_name}-{self.Foundation_year}"

    @play_match
    def win(self):
        self.Points_of_season += 3

    @play_match
    def draw(self):
        self.Points_of_season += 1

    @play_match
    def lose(self):
        pass

【问题讨论】:

    标签: python django python-decorators


    【解决方案1】:

    像任何其他装饰器一样。装饰器函数的参数应该只是函数,然后你在装饰器函数中定义你的子函数,它将在执行你的函数之前进行“装饰”。所以在这种情况下,我的装饰器函数是play_match,它定义了add_one,它接受了self参数,因此它可以访问类变量。然后它增加 Match_Played 并调用传递给装饰器的函数。

    class Team:
        Team_Name = ""
        Foundation_year = 0
        Points_of_season = 0
        Match_Played = 0
        League = "league"
    
        def __str__(self):
            return f"{self.Team_name}-{self.Foundation_year}"
    
        def play_match(func):
            def add_one(self):
                self.Match_Played += 1
                func(self)
            return add_one
    
        @play_match
        def win(self):
            self.Points_of_season += 3
    
        @play_match
        def draw(self):
            self.Points_of_season += 1
    
        @play_match
        def lose(self):
            pass
    
    x = Team()
    x.win()
    print("Num matches: ", x.Match_Played)
    x.draw()
    print("Num matches: ", x.Match_Played)
    

    输出:

    Num matches:  1
    Num matches:  2
    

    【讨论】:

    • 为什么是 func(self)?
    • @MohamedFaresBenAyed 因为类方法需要一个 self 参数。就像 d_kennetz 说的,“装饰器函数的参数应该只是函数,然后你在装饰器函数中定义你的子函数”
    • @MohamedFaresBenAyed 这是否有助于解决您的问题?如果是这样,您应该将其标记为问题的已接受答案。
    • 完成!我接受了,抱歉我忘记接受了
    • @MohamedFaresBenAyed 很高兴它有帮助,不用担心!
    猜你喜欢
    • 2020-11-03
    • 2016-01-28
    • 2016-03-14
    • 2014-04-14
    • 2022-11-23
    • 1970-01-01
    • 2018-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多