Как я могу обрабатывать динамические вычисляемые атрибуты в модели в Django? - PullRequest
1 голос
/ 04 мая 2010

В Django я вычисляю хлебные крошки (список отцов) для географического объекта. Поскольку он не будет меняться очень часто, я подумываю предварительно рассчитать его после сохранения или инициализации объекта.

1.) Что было бы лучше? Какое решение будет иметь лучшую производительность? Чтобы вычислить его в ____init____ или рассчитать при сохранении объекта (объект занимает около 500-2000 символов в БД)?

2.) Я пытался перезаписать методы ____init____ или save (), но не знаю, как использовать атрибуты только что сохраненного объекта. Доступ к * args, ** kwargs не работал. Как я могу получить к ним доступ? Должен ли я сохранить, получить доступ к отцу, а затем снова сохранить?

3.) Если я решу сохранить хлебную крошку. Какой лучший способ сделать это? Я использовал http://www.djangosnippets.org/snippets/1694/ и имею crumb = PickledObjectField ().

Модель:

class GeoObject(models.Model):
    name = models.CharField('Name',max_length=30)
    father = models.ForeignKey('self', related_name = 'geo_objects')
    crumb = PickledObjectField()
    # more attributes...

Это метод для вычисления атрибута crumb ()

def _breadcrumb(self):
    breadcrumb = [ ]
    x = self
    while True:
        x = x.father
        try:
            if hasattr(x, 'country'):
                breadcrumb.append(x.country)
            elif hasattr(x, 'region'):
                breadcrumb.append(x.region)
            elif hasattr(x, 'city'):
                breadcrumb.append(x.city)
            else:
                break
        except:
            break
    breadcrumb.reverse()
    return breadcrumb

Вот мой метод сохранения:

def save(self,*args, **kwargs):
    # how can I access the father ob the object?
    father = self.father # does obviously not work
    father = kwargs['father'] # does not work either 

    # the breadcrumb gets calculated here
    self.crumb = self._breadcrumb(father)
    super(GeoObject, self).save(*args,**kwargs)

Пожалуйста, помогите мне. Я работаю над этим уже несколько дней. Спасибо.

1 Ответ

0 голосов
/ 04 мая 2010

Вызывая метод _breadcrumb с помощью x.father и назначая x = x.father в начале цикла while, вы перепрыгиваете через одного отца. Попробуйте обменять

self.crumb = self._breadcrumb(father) 

с

self.crumb = self._breadcrumb(self)

Определив _breadcrumb в классе модели, вы можете очистить его следующим образом:

class GeoObject(models.Model):
    name = models.CharField('Name',max_length=30)
    father = models.ForeignKey('self', related_name = 'geo_objects')
    crumb = PickledObjectField()
    # more attributes...

    def _breadcrumb(self):
        ...
        return breadcrumb

    def save(self,*args, **kwargs):
        self.crumb = self._breadcrumb()
        super(GeoObject, self).save(*args,**kwargs)

Для более сложных иерархий я рекомендую django-treebeard

...