Django: обнаружение изменений набора полей при сохранении модели - PullRequest
6 голосов
/ 29 ноября 2010

проблема

В моей модели есть поле, которое требует некоторых вычислений. Я хочу выполнить эти вычисления при сохранении модели. Однако, поскольку это ресурсоемкий процесс, я хочу выполнять эти вычисления только при изменении определенных полей.

Начальная мысль

Сохраните хэш 3 полей как отдельное поле в модели. При сохранении хэш трех полей и, если оно совпадает с тем, которое в данный момент сохранено в модели, продолжить сохранение экземпляра без дальнейшей работы. В противном случае выполните вычисления, сохраните результаты расчета и сохраните новый хеш.

Мои вопросы:

  1. Это лучший вариант? Если нет, пожалуйста, поделитесь, что было бы лучше и почему.

  2. Если нет лучшего способа: какой тип хэша я должен использовать? И почему?

  3. Какой тип поля модели Django следует использовать для сохранения хеша?

Ответы [ 3 ]

4 голосов
/ 30 ноября 2010

Я представляю реализацию моей первоначальной мысли в качестве ответа, который будет подвергнут критике со стороны других:

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

Если у кого-то есть какие-либо предложения, комментарии или проблемы; пожалуйста поделитесь!

1 голос
/ 29 ноября 2010

Укажите аргумент запроса для метода сохранения и определите этот пользовательский метод сохранения:

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
0 голосов
/ 27 июня 2013

Почему бы не сравнить экземпляр с БД ... что-то вроде:

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 )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...