【问题标题】:How can I handle dynamic calculated attributes in a model in Django?如何处理 Django 模型中的动态计算属性?
【发布时间】:2010-05-04 07:45:45
【问题描述】:

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

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

【问题讨论】:

  • 但是father 是什么?您说访问self.father 显然 不起作用,但为什么不呢?它到底是什么?
  • 父亲是模型中的属性之一。我现在添加了模型的示例代码。显然我的意思是,我无法访问该对象,因为它尚未保存。
  • 这根本不符合。如果您有父亲(这里通常的英文单词是 parent,但这没关系),无论您是否已保存,都可以访问。如果你没有一个,那么你的代码中就没有设置一个,所以你保存后仍然不会有一个。

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


【解决方案1】:

通过使用 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-19
    • 2016-03-17
    • 2017-06-24
    • 1970-01-01
    • 1970-01-01
    • 2020-03-10
    • 1970-01-01
    • 2018-12-06
    相关资源
    最近更新 更多