Django:在模型保存时检测一组字段的变化

6 投票
3 回答
3406 浏览
提问于 2025-04-16 07:47

问题

我在我的模型里有一个字段需要进行一些计算。我希望在保存模型的时候进行这些计算。不过因为这些计算比较耗资源,所以我只想在某些字段发生变化的时候才进行计算。

初步想法

我可以把这三个字段的哈希值作为模型中的一个不同字段。在保存的时候,先计算这三个字段的哈希值,如果和当前模型里保存的哈希值相等,就直接保存实例,不再做其他工作。否则,就进行计算,保存计算结果,并更新哈希值。

我的问题:

  1. 这是最好的选择吗?如果不是,请分享更好的方法以及原因。

  2. 如果没有更好的方法:我应该使用哪种哈希?为什么?

  3. 我应该使用哪种Django模型字段类型来保存哈希值?

3 个回答

0

为什么不把这个实例和数据库进行比较呢...可以这样做:

class MyModel( models.Model ):
    description = models.CharField( max_length=12 )

    def save(self, *args, **kwargs):
        if not MyModel.objects.filter( id = self.id, description__exact = self.description ).exists():
            ### do complex logic here ###
        super( MyModel, self ).save( *args, **kwargs )
1

给保存方法提供请求参数,并定义这个自定义的保存方法:

def save(self, request=False, *args, **kwargs):
    if request and request.POST.get('var1',False) and request.POST.get('var2',False) and request.POST.get('var3',False):
        ######
        ##Do your calculations
        ######
    super(Model, self).save(*args, **kwargs)

把你的 admin.py 更新成下面这样:

class ModelAdmin(admin.ModelAdmin):

    ....
    def save_model(self, request, obj, form, change): 
        instance = form.save(commit=False)
        instance.save(request=request)
        return instance
4

我把我最初的想法实现的代码提交上来,希望大家能给我一些意见和建议:

models.py

from hashlib import md5

class Stop(models.Model):
    line = models.CharField(max_length=12)
    street = models.CharField(max_length=32, choices=STREET_CHOICES)
    order = models.PositiveIntegerField(blank=True, null=True)
    location_hash = models.CharField(max_length=32, null=True)

    def save(self):
        location_hash = md5('%s@%s' % (self.line, self.street))
        if self.location_hash != location_hash:
            self.order = calculate_order(line=self.line, street=self.street)
            self.location_hash = location_hash
        super(Stop, self).save()

如果有人有任何建议、评论或疑虑,分享出来!

撰写回答