关于将模型中的自定义函数转换为自定义中的注解managers/querysets
About converting custom functions in models into annotations in custom managers/querysets
作为 Django 的新手,我开始有点关心我的 Web 应用程序的性能。
我正在尝试将我模型中的许多自定义函数/属性转换为自定义管理器中的查询集。
在我的模型中我有:
class Shape(models.Model):
@property
def nb_color(self):
return 1 if self.colors=='' else int(1+sum(self.colors.upper().count(x) for x in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'))
def __str__(self):
return self.name + "-" + self.constraints
@property
def image_url(self):
return format_html(f'{settings.SVG_DIR}/{self}.svg')
@property
def image_src(self):
return format_html('<img src="{url}"|urlencode />'.format(url = self.image_url))
def image_display(self):
return format_html(f'<a href="/static/SVG_shapes/{self}">{self.image_src}"</a>')
但是有几点我不是很清楚:
1/ 在 django 模型中使用适当的装饰器声明是否有任何优点或缺点?
2/ 就数据库调用而言,调用 function/property 的成本是多少
因此,使用自定义管理器/查询集并定义注释以在该级别模拟我的功能是否有附加值?
3/ 你建议我如何将图像和 nb_color 函数转换为注释
提前致谢
PS: 图像相关的功能,我想通了:
self.annotate(image_url = Concat(Value(join(settings.SVG_DIR,'')), F('fullname'), Value('.svg'), output_field=CharField()),
image_src = Concat(Value('<img src="'), F('image_url'), Value('"|urlencode />'), output_field=CharField()),
image_display = Concat(Value('<a href="'+ settings.SVG_DIR+'/'), F('fullname'), Value('.svg">'),F('image_src'), Value('</a>'), output_field=CharField()),
)
但是 image_src 的显示有问题
通过:
readonly_fields=['image']
def image(self, obj):
return format_html(obj.image_src)
虽然地址没问题,但好像找不到图片
如果有人有想法...
PS: For the image related functions, I mostly figured it out:
self.annotate(image_url = Concat(Value(join(settings.SVG_DIR,'')),
F('fullname'), Value('.svg'), output_field=CharField()),
image_src = Concat(Value(''), output_field=CharField()),
image_display = Concat(Value(''),F('image_src'),
Value(''), output_field=CharField()),
) I am however having an issue for the display of image_src through:
readonly_fields=['image'] def image(self, obj):
return format_html(obj.image_src) it doesn't seem to find the image while the adress is ok.
我想出了我的图像问题:我应该简单地使用相对路径并让 Django 管理:
self.annotate(image_url = Concat(Value('/static/SVG_shapes/'), F('fullname'), Value('.svg'), output_field=CharField()),)
有了现在 1.5 年的经验,我将尝试回答我的新手问题,以供下一个可能有相同问题的人想到。
1/ 在 django 模型中使用 propriety 装饰器声明是否有任何优点或缺点?
到目前为止我还没有看到任何缺点。
它允许将数据检索为模型的 属性 (my_shape.image_url
),而不必调用相应的方法 (my_shape.image_url()
)
然而,出于不同的目的,我更喜欢有一个可调用的(方法)而不是 属性
2/ 就数据库调用而言,调用 function/property 的成本是多少
如果需要作为输入的数据已经可用,或者它们本身是实例对象的属性(不需要从实例对象外部输入的字段/属性/方法),则无需额外调用数据库
但是,如果需要外部数据,将为每个数据生成一个数据库调用。
因此,使用 @cached_property
装饰器而不是 @property
装饰器
来缓存这样 属性 的结果可能很有价值
唯一需要使用缓存属性的是以下导入:
from django.utils.functional import cached_property
第一次调用后,缓存的 属性 将在对象实例的整个生命周期内保持可用,无需额外费用,
其内容可以像任何其他 属性 / 变量一样进行操作:
因此,使用自定义管理器/查询集并定义注释以在该级别模拟我的功能是否有附加值?
根据我目前的理解和实践,在 属性 和管理器
中复制相同的功能并不少见
原因是当我们只对一个特定的对象实例感兴趣时,属性很容易获得,
当您有兴趣比较/检索一系列对象的给定 属性 时,为整个查询集计算和注释此 属性 会更有效,例如通过使用模型管理器
我的赠品是:
对于给定的模型,
(1) 尝试将涉及单个对象实例的所有业务逻辑放入模型方法/属性中
(2) 和所有涉及一系列对象的业务逻辑进入模型管理器
3/ 你建议我如何将图像和 nb_color 函数转换为注释
已在之前的回答中回答
作为 Django 的新手,我开始有点关心我的 Web 应用程序的性能。
我正在尝试将我模型中的许多自定义函数/属性转换为自定义管理器中的查询集。
在我的模型中我有:
class Shape(models.Model):
@property
def nb_color(self):
return 1 if self.colors=='' else int(1+sum(self.colors.upper().count(x) for x in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'))
def __str__(self):
return self.name + "-" + self.constraints
@property
def image_url(self):
return format_html(f'{settings.SVG_DIR}/{self}.svg')
@property
def image_src(self):
return format_html('<img src="{url}"|urlencode />'.format(url = self.image_url))
def image_display(self):
return format_html(f'<a href="/static/SVG_shapes/{self}">{self.image_src}"</a>')
但是有几点我不是很清楚:
1/ 在 django 模型中使用适当的装饰器声明是否有任何优点或缺点?
2/ 就数据库调用而言,调用 function/property 的成本是多少
因此,使用自定义管理器/查询集并定义注释以在该级别模拟我的功能是否有附加值?
3/ 你建议我如何将图像和 nb_color 函数转换为注释
提前致谢
PS: 图像相关的功能,我想通了:
self.annotate(image_url = Concat(Value(join(settings.SVG_DIR,'')), F('fullname'), Value('.svg'), output_field=CharField()),
image_src = Concat(Value('<img src="'), F('image_url'), Value('"|urlencode />'), output_field=CharField()),
image_display = Concat(Value('<a href="'+ settings.SVG_DIR+'/'), F('fullname'), Value('.svg">'),F('image_src'), Value('</a>'), output_field=CharField()),
)
但是 image_src 的显示有问题 通过:
readonly_fields=['image']
def image(self, obj):
return format_html(obj.image_src)
虽然地址没问题,但好像找不到图片
如果有人有想法...
PS: For the image related functions, I mostly figured it out:
self.annotate(image_url = Concat(Value(join(settings.SVG_DIR,'')), F('fullname'), Value('.svg'), output_field=CharField()), image_src = Concat(Value(''), output_field=CharField()), image_display = Concat(Value(''),F('image_src'), Value(''), output_field=CharField()), ) I am however having an issue for the display of image_src through:
readonly_fields=['image'] def image(self, obj): return format_html(obj.image_src) it doesn't seem to find the image while the adress is ok.
我想出了我的图像问题:我应该简单地使用相对路径并让 Django 管理:
self.annotate(image_url = Concat(Value('/static/SVG_shapes/'), F('fullname'), Value('.svg'), output_field=CharField()),)
有了现在 1.5 年的经验,我将尝试回答我的新手问题,以供下一个可能有相同问题的人想到。
1/ 在 django 模型中使用 propriety 装饰器声明是否有任何优点或缺点?
到目前为止我还没有看到任何缺点。
它允许将数据检索为模型的 属性 (my_shape.image_url
),而不必调用相应的方法 (my_shape.image_url()
)
然而,出于不同的目的,我更喜欢有一个可调用的(方法)而不是 属性
2/ 就数据库调用而言,调用 function/property 的成本是多少
如果需要作为输入的数据已经可用,或者它们本身是实例对象的属性(不需要从实例对象外部输入的字段/属性/方法),则无需额外调用数据库
但是,如果需要外部数据,将为每个数据生成一个数据库调用。
因此,使用 @cached_property
装饰器而不是 @property
装饰器
唯一需要使用缓存属性的是以下导入:
from django.utils.functional import cached_property
第一次调用后,缓存的 属性 将在对象实例的整个生命周期内保持可用,无需额外费用, 其内容可以像任何其他 属性 / 变量一样进行操作:
因此,使用自定义管理器/查询集并定义注释以在该级别模拟我的功能是否有附加值?
根据我目前的理解和实践,在 属性 和管理器
中复制相同的功能并不少见原因是当我们只对一个特定的对象实例感兴趣时,属性很容易获得, 当您有兴趣比较/检索一系列对象的给定 属性 时,为整个查询集计算和注释此 属性 会更有效,例如通过使用模型管理器
我的赠品是: 对于给定的模型, (1) 尝试将涉及单个对象实例的所有业务逻辑放入模型方法/属性中 (2) 和所有涉及一系列对象的业务逻辑进入模型管理器
3/ 你建议我如何将图像和 nb_color 函数转换为注释
已在之前的回答中回答