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

发布于 2024-08-31 02:10:38 字数 1633 浏览 3 评论 0原文

在 Django 中,我计算了地理对象的面包屑(父亲列表)。由于它不会经常更改,因此我正在考虑在保存或初始化对象后预先计算它。

1.) 什么会更好?哪种解决方案会有更好的性能?在____init____处计算它还是在保存对象时计算它(该对象在数据库中占用大约500-2000个字符)?

2.) 我尝试覆盖____init____ 或save() 方法,但我不知道如何使用刚刚保存的对象的属性。访问 *args、**kwargs 不起作用。我如何访问它们?我是否必须保存,访问父亲,然后再次保存?

3.) 如果我决定保存面包屑。最好的方法是什么?我使用 http://www.djangosnippets.org/snippets/1694/ 并有面包屑= 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)

请帮帮我。我已经为此工作好几天了。谢谢。

In Django I calculate the breadcrumb (a list of fathers) for an geographical object. Since it is not going to change very often, I am thinking of pre calculating it once the object is saved or initialized.

1.) What would be better? Which solution would have a better performance? To calculate it at ____init____ or to calculate it when the object is saved (the object takes about 500-2000 characters in the DB)?

2.) I tried to overwrite the ____init____ or save() methods but I don't know how to use attributes of the just saved object. Accessing *args, **kwargs did not work. How can I access them? Do I have to save, access the father and then save again?

3.) If I decide to save the breadcrumb. Whats the best way to do it? I used http://www.djangosnippets.org/snippets/1694/ and have crumb = PickledObjectField().

The model:

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

Thats the method to calculate the attribute 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

Thats my save-Method:

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)

Please help me out. I am working on this for days now. Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

烏雲後面有陽光 2024-09-07 02:10:38

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

By calling both the _breadcrumb method with x.father and assigning x = x.father in the beginning of the while loop you jump over one father. Try exchanging

self.crumb = self._breadcrumb(father) 

with

self.crumb = self._breadcrumb(self)

By defining _breadcrumb within the model class you can clean it up like this:

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)

For more complex hierachies I recomend django-treebeard

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文