如何在Django中处理模型中的动态计算属性?

时间:2010-05-04 07:45:45

标签: python django oop django-models django-signals

在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 :(得分:0)

通过在x.father中调用_breadcrumb方法并在while循环的开头分配x = x.father,你跳过一个父亲。尝试交换

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