1

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

请帮帮我。我正在为此工作几天。谢谢你。

4

1 回答 1

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

于 2010-05-04T10:29:55.953 回答