Django:保存模型时检测一组字段的更改

发布于 2024-10-05 05:18:20 字数 368 浏览 0 评论 0原文

问题

我的模型中有一个字段需要一些计算。我想在保存模型时执行这些计算。但是,因为它是资源密集型的,所以我只想在某些字段发生更改时才执行这些计算。

最初的想法

将 3 个字段的哈希值保留为模型中的不同字段。保存时,对三个字段进行哈希处理,如果等于模型中当前保存的字段,则继续保存实例,无需进一步工作。否则,执行计算,保存计算结果并保存新的哈希值。

我的问题:

  1. 这是最好的选择吗?如果不是,请分享什么会更好以及为什么。

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

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

The problem

I have a field in my model that requires some calculation. I want to perform these calculations when the model is saved. However, because it is resource intensive, I want to only perform these calculations when certain fields have changed.

Initial thought

Keep the hash of the 3 fields as a different field in the model. On save, hash the three fields and, if equal to the the one currently saved in the model, continue on saving the instance without further work. Otherwise, perform calculations, save the results of the calculation and save new hash.

My questions:

  1. Is this the best option? If not, please share what would be better and why.

  2. If there isn't a better way: Which kind of hash should I use? And why?

  3. Which kind of Django model field type should I use to save the hash?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情徒 2024-10-12 05:18:20

我正在提交我最初想法的实现,作为其他人批评的答案:

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()

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

I am submitting the implementation of my initial thought as an answer to be critiqued by others:

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()

If anyone has any suggestions, comments or concerns; please share!

静赏你的温柔 2024-10-12 05:18:20

向 save 方法提供请求参数并定义此自定义保存方法:

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

Supply request argument to the save method and define this custom save method:

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)

Update your admin.py to something like this:

class ModelAdmin(admin.ModelAdmin):

    ....
    def save_model(self, request, obj, form, change): 
        instance = form.save(commit=False)
        instance.save(request=request)
        return instance
哀由 2024-10-12 05:18:20

为什么不将实例与数据库进行比较...类似:

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 )

Why not compare the instance with the db... something like:

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 )
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文