我有一些我需要使用自定义SQL的东西。刚开始,我不想讨论为什么我们使用自定义SQL。那是旧的,无关紧要的。
无论如何,使用这个自定义SQL,我正在填充模型并尝试填充相关/子模型。这一切似乎都很顺利,直到在视图或模板中访问相关模型。如果我这样做,django会启动另一个SQL查询,这是完全没必要的,因为我已经通过第一个查询得到了数据。
以下是示例,修剪过的模型:
class Preferredname(models.Model):
preferredname_id = models.CharField(primary_key=True, max_length=1)
name = models.CharField(max_length=255)
class PersonCustom(models.Manager):
def getSpecial(self):
from django.db import connection, transaction
curse = DictCursor(connection.cursor())
curse.execute("SELECT * FROM person WHERE special = 't'")
result_list = []
for row in curse.fetchall():
i = self.model(
firstname = row['firstname'],
middlename = row['middlename'],
nickname = row['nickname'],
lastname = row['lastname'],
suffix = row['suffix'],
)
i.preferredname = Preferredname()
i.preferredname.preferredname_id = row['preferredname_id']
result_list.append(i)
return result_list
class Person(models.Model):
person_id = models.IntegerField(primary_key=True)
firstname = models.CharField(max_length=255, blank=True)
middlename = models.CharField(max_length=255, blank=True)
lastname = models.CharField(max_length=255, blank=True)
nickname = models.CharField(max_length=255, blank=True)
suffix = models.CharField(max_length=255, blank=True)
preferredname = models.ForeignKey(Preferredname)
objects = PersonCustom()
def get_preferred_name(self):
try:
if self.preferredname.preferredname_id == 'N':
pref = self.nickname
elif self.preferredname.preferredname_id == 'M':
pref = self.middlename
else:
pref = self.firstname
except ObjectDoesNotExist:
if self._preferred_name == 'N':
pref = self.nickname
elif self._preferred_name == 'M':
pref = self.middlename
else:
pref = self.firstname
name = "%s %s %s" % (pref, self.lastname, self.suffix)
return name.strip()
def set_preferred_name(self, val):
self._preferred_name = val
preferred_name = property(get_preferred_name, set_preferred_name)
举个例子:
>>> p = Person.objects.getSpecial()
>>> p[0].preferred_name
由于get_preferred_name()方法访问self.preferredname.preferredname_id(理论上应该已经填充),因此它会对preferredname进行另一次查询。
我不在这里,或者这应该按照我的意愿行事吗?如果我离开这里,有没有办法从自定义管理器中填充相关模型?
答案 0 :(得分:1)
不要将对象分配给i.preferredname
,而是尝试将其设置为i._preferredname_cache
,这是Django用于缓存外键查找的内部对象。这应该有用。