gpt4 book ai didi

python - Django:可查询的计算字段

转载 作者:行者123 更新时间:2023-11-30 22:19:45 24 4
gpt4 key购买 nike

是否有一种“最佳”方法来执行可查询的计算字段?

例如:

from django.db import models

class Person(models.Model):
given_name = models.CharField(max_length=30)
family_name = models.CharField(max_length=30)

NAME_ORDER_CONVENTION_CHOICES = (
# "Eastern" name order: family name followed by given name
('E', 'Eastern'),
# "Western" name order: given name followed by family name
('W', 'Western')
)

name_order_convention = models.CharField(
length=1,
choices=NAME_ORDER_CONVENTION_CHOICES,
)

@property
def full_name(self):
"""
Return full name, calculated on the basis of given name,
family name and name order convention.
"""
template = "{} {}"
if self.name_order_convention == "W":
return template.format(self.given_name, self.family_name)
return template.format(self.family_name, self.given_name)

这使您能够获取任何Personfull_name,但是如果您想根据全名进行数据库查询,则需要编写查询隐式了解如何计算此属性。这似乎违反了 DRY,因为不再有任何中心位置可以更改计算字段的计算方式 - 您必须在任何地方更改 full_name 属性它基于 full_name 工作原理的隐式知识进行查询。

我能想到的主要替代方案是重写 save() 方法以在每次更新时更新这些字段。

from django.db import models

class Person(models.Model):
given_name = models.CharField(max_length=30)
family_name = models.CharField(max_length=30)

NAME_ORDER_CONVENTION_CHOICES = (
('E', 'Eastern'),
('W', 'Western')
)

name_order_convention = models.CharField(
length=1,
choices=NAME_ORDER_CONVENTION_CHOICES,
)

# Computed fields
full_name = models.CharField(max_length=60)

def _calculate_full_name(self):
template = "{} {}"
if self.name_order_convention == "W":
self.full_name = template.format(self.given_name, self.family_name)
else:
self.full_name = template.format(self.family_name, self.given_name)

def save(self, *args, **kwargs):
self._calculate_full_name()
super(Model, self).save(*args, **kwargs)

对于我可能缺少的可查询计算字段,是否有一个通用的“最佳实践”解决方案?

最佳答案

我可以看到的一种方法:在数据库中创建 View ,并使用连接的全名而不是django中的托管模型来用于查询(Person模型也应该存在于增删改查操作):

查看(postgresql)

CREATE OR REPLACE VIEW appname_viewperson AS 
SELECT id,
given_name,
family_name,
given_name || ' ' || family_name AS full_name,
FROM appname_person

非托管模型:

class ViewPerson(models.Model):
given_name = models.CharField(max_length=30)
family_name = models.CharField(max_length=30)
full_name = models.CharField(max_length=60)

class Meta:
managed = False

关于python - Django:可查询的计算字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49032297/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com