Skip to main content
 首页 » 编程设计

python之如何在 Django 模型中存储函数

2024年08月30日33unruledboy

编辑:我完全重写了问题,因为原来的问题没有清楚地解释我的问题

我想运行一个特定于每个特定模型实例的函数。

理想情况下我想要这样的东西:

class MyModel(models.Model): 
    data = models.CharField(max_length=100) 
    perform_unique_action = models.FunctionField() #stores a function specific to this instance 
 
x = MyModel(data='originalx', perform_unique_action=func_for_x) 
x.perform_unique_action() #will do whatever is specified for instance x 
 
y = MyModel(data='originaly', perform_unique_action=func_for_y) 
y.perform_unique_action() #will do whatever is specified for instance y 

但是没有数据类型 FunctionField。通常这可以通过继承和创建 MyModel 的子类来解决,可能像这样:

class MyModel(models.Model): 
    data = models.CharField(max_length=100) 
    perform_unique_action = default_function 
 
class MyModelX(MyModel): 
    perform_unique_action = function_X 
 
class MyModelY(MyModel): 
    perform_unique_action = function_Y 
 
x = MyModelX(data='originalx') 
x.perform_unique_action() #will do whatever is specified for instance x 
 
y = MyModelY(data='originaly') 
y.perform_unique_action() #will do whatever is specified for instance y 

不幸的是,我不认为我可以使用继承,因为我试图以这种方式访问​​函数:

class MyModel(models.Model): 
    data = models.CharField(max_length=100) 
    perform_unique_action = default_function 
 
class SecondModel(models.Model): 
    other_data = models.IntegerField() 
    mymodel = models.ForeignKey(MyModel) 
 
secondmodel = SecondModel.objects.get(other_data=3) 
secondmodel.mymodel.perform_unique_action() 

问题似乎是,如果我重写子类中的 perform_unique_action,我不知道外键在 SecondModel 中的类型。

我能否从 SecondModel 访问 MyModel 作为外键,并且仍然为 MyModel 的每个实例提供唯一的函数?

请您参考如下方法:

这对我有用。我还没有测试过它,但你应该能够创建另一个类并覆盖它们的方法,它会起作用。检查 class Meta 行,它会将其视为抽象类。这是我现在正在处理的实际类(class)的示例。

编辑:添加了 VoteComment 类并对其进行了测试。它按预期工作!

class Vote(models.Model): 
    VOTE_ENUM = ( 
        (VoteEnum.DOWN_VOTE, VoteEnum.toString(VoteEnum.DOWN_VOTE)), 
        (VoteEnum.NONE, VoteEnum.toString(VoteEnum.NONE)), 
        (VoteEnum.UP_VOTE, VoteEnum.toString(VoteEnum.UP_VOTE)), 
 
    ) 
    question = models.ForeignKey(Question, null=False, editable=False, blank=False) 
    voter = models.ForeignKey(User, blank=False, null=False, editable=False) 
    vote_type = models.SmallIntegerField(default=0, null=False, blank=False, choices=VOTE_ENUM) 
 
    class Meta: 
        abstract = True 
 
    def is_upvote(self): 
        return self.vote_type > 0 
    def is_downvote(self): 
        return self.vote_type < 0 
 
class VoteAnswer(Vote): 
    answer = models.ForeignKey(Answer, null=False, editable=False, blank=False) 
 
    class Meta: 
        unique_together = (("voter", "answer"),) # to prevent user from voting on the same question/answer/comment again 
 
    def __unicode__(self): 
        vote_type = "UP" if vote_type > 0 else ("DOWN" if vote_type < 0 else "NONE") 
        return u"{0}: [{1}] {2}".format(user.username, vote_type, answer.text[:32]) 
 
    def is_upvote(self): 
        return "FOO! "+str(super(VoteAnswer, self).is_upvote()) 
 
class VoteComment(Vote): 
    comment = models.ForeignKey(Comment, null=False, editable=False, blank=False) 
 
    class Meta: 
        unique_together = (("voter", "comment"),) # to prevent user from voting on the same question/answer/comment again 
 
    def __unicode__(self): 
        vote_type = "UP" if vote_type > 0 else ("DOWN" if vote_type < 0 else "NONE") 
        return u"{0}: [{1}] {2}".format(user.username, vote_type, comment.text[:32]) 
 
    def is_upvote(self): 
        return "BAR!"