作为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 /就数据库调用而言,调用函数/属性的成本是多少
,因此,使用自定义管理器/查询集并定义注释以在该级别模拟我的功能是否有附加值?
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)
地址正确时似乎找不到图像。
如果有人有主意...
答案 0 :(得分:0)
PS:对于图像相关的功能,我主要是弄清楚了:
self.annotate(image_url = Concat(Value(join(settings.SVG_DIR,'')), F('全名'),Value('。svg'),output_field = CharField()), image_src = Concat(Value(''),output_field = CharField()), image_display = Concat(Value(''),F('image_src'), 值(''),output_field = CharField()), )但是我在通过以下方式显示image_src时遇到问题:
readonly_fields = ['image'] def image(self,obj): 返回format_html(obj.image_src),但在地址正常时似乎找不到图像。
我想出了我的图像问题:我应该简单地使用相对路径并让Django管理:
self.annotate(image_url = Concat(Value('/static/SVG_shapes/'), F('fullname'), Value('.svg'), output_field=CharField()),)
答案 1 :(得分:0)
现在有了 1.5 年的经验,我将尝试为下一个可能会出现相同问题的人回答我的新手问题。
1/ 在 django 模型中使用专有装饰器声明有什么优点或缺点吗?
目前我看不到任何缺点。
它允许将数据作为模型的属性(my_shape.image_url
)进行检索,而不必调用相应的方法(my_shape.image_url()
)
然而,出于不同的目的,我更喜欢有一个可调用的(方法)而不是一个属性
2/ 就数据库调用而言,调用函数/属性的成本是多少
如果数据库需要作为输入的数据已经可用,或者它们本身就是实例对象的属性(不需要从实例对象外部输入的字段/属性/方法),则无需额外调用数据库
但是,如果需要外部数据,则会为每个数据生成一个数据库调用。
因此,通过使用 @cached_property
装饰器而不是 @property
装饰器来缓存此类属性的结果可能很有价值
使用缓存属性唯一需要的是以下导入:
from django.utils.functional import cached_property
第一次调用后,缓存的属性将在对象实例的整个生命周期内保持可用,无需额外成本, 并且它的内容可以像任何其他属性/变量一样被操纵:
因此,使用自定义管理器/查询集并定义注释来模拟我在该级别的功能是否有附加价值?
在我目前的理解和实践中,在财产和经理中复制相同的功能并不少见
原因是当我们只对一个特定的对象实例感兴趣时,属性很容易获得, 而当您有兴趣比较/检索一系列对象的给定属性时,为整个查询集计算和注释此属性会更有效,例如通过使用模型管理器
我的赠品是: 对于给定的模型, (1) 尝试将涉及单个对象实例的所有业务逻辑放入模型方法/属性中 (2) 和所有涉及一系列对象的业务逻辑到模型管理器中
3/ 你如何建议我将我的图像和 nb_color 函数转换为注释
已经在之前的回答中回答了