这似乎很简单,我忽略了,但无论如何都要进行。
我定义了一个模型,我想从模型中检索某些列(不是通过QuerySet API /模型管理器),而是在模型类中。
示例:
class mymodel(models.Model):
col1 = ...
col2 = ...
col3 = ...
def __unicode__(self):
return '%s %s' % (self.col1, self.col3) # Notice I'm omitting col2.
在__unicode__
类方法中,这至少计为2个数据库查询。如何在仅1个数据库查询中检索此类方法中的col1和col3?似乎它应该是如此简单,我觉得我做的事情是愚蠢的。
更新:
根据反馈,我创建了一个测试模型,测试表等...并找到了几个用户说的正确。但是,在我的实际代码中(使用多个表单),更改__unicode__
方法以返回一列连接值会更改SQL查询的数量从601变为34.我只更改了单线。根据我的测试用例,可能还有其他事情正在发生,但重申一下,我只更改了unicode方法,并且我的数据库命中数量大不相同。
我不确定我的其他代码发生了什么,我将不得不尝试更仔细地看一下。同时这里是测试用例,证明你们是正确的:
# Models.py
class TestModelFK(models.Model):
col1 = models.CharField(max_length=8)
col2 = models.CharField(max_length=8)
col3 = models.CharField(max_length=8)
col4 = models.CharField(max_length=8)
allcols = models.CharField(max_length=32, blank=True, editable=False)
class Meta:
ordering = ('col1', 'col2')
def __unicode__(self):
return '%s %s %s %s' % (self.col1, self.col2, self.col3, self.col4)
def save(self, *args, **kwargs):
self.allcols = '%s %s %s %s' % (self.col1, self.col2, self.col3, self.col4)
super(TestModelFK, self).save()
class TestModel(models.Model):
quantity = models.IntegerField()
test_fk = models.ForeignKey(TestModelFK)
# forms.py
class TestModelForm(forms.ModelForm):
class Meta:
model = TestModel
# views.py
if request.method == 'GET':
post['TestModelFormSet'] = formset_factory(TestModelForm, extra=4)
答案 0 :(得分:1)
__unicode__
方法调用作为内存中调用发生。它不会触发单独的DB调用。
答案 1 :(得分:1)
我猜你在做这个
myModelInstance = MyModel.objects().get(id=1)
然后
print myModelInstance
>> "WhateverCol1is WhateverCol2is"
这绝对会触发1个数据库调用,因为您必须获取该模型实例。
这就是get()
所做的,它会立即获取对象。
由于您已经省略了字段声明,我猜测col1
或col3
是ManyToMany
字段还是ForeignKey
,因此在获取实例时将获取字段引用的行。
如果你有一个像这样完成的QuerySet
myModelInstances = MyModel.objects().filter(id=1)
并迭代它,它将评估它并需要 n 数据库调用。
QuerySets是惰性的,只在某些事情发生时进行评估(即进入数据库),这些是
list()
len()
repr()
详细了解QuerySet here
答案 2 :(得分:1)
让我们来看看你的功能:
def __unicode__(self):
return '%s %s' % (self.col1, self.col3) # Notice I'm omitting col2.
当您调用__unicode__
时,您的模型已经在内存中。您可以根据需要访问self
中的字段,此时无法访问数据库。