Django如何在单个模型实例上选择多个列

时间:2013-09-19 04:55:50

标签: django model

这似乎很简单,我忽略了,但无论如何都要进行。

我定义了一个模型,我想从模型中检索某些列(不是通过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)

3 个答案:

答案 0 :(得分:1)

__unicode__方法调用作为内存中调用发生。它不会触发单独的DB调用。

答案 1 :(得分:1)

我猜你在做这个

myModelInstance = MyModel.objects().get(id=1)

然后

print myModelInstance
>> "WhateverCol1is WhateverCol2is"

这绝对会触发1个数据库调用,因为您必须获取该模型实例。 这就是get()所做的,它会立即获取对象。

由于您已经省略了字段声明,我猜测col1col3ManyToMany字段还是ForeignKey,因此在获取实例时将获取字段引用的行。

如果你有一个像这样完成的QuerySet

myModelInstances = MyModel.objects().filter(id=1)

并迭代它,它将评估它并需要 n 数据库调用。

QuerySets是惰性的,只在某些事情发生时进行评估(即进入数据库),这些是

  • 迭代QuerySet
  • 切片查询集
  • 在QuerySet上使用list()
  • 使用len()
  • 使用repr()
  • 腌制或缓存QuerySet

详细了解QuerySet here

答案 2 :(得分:1)

让我们来看看你的功能:

def __unicode__(self):
    return '%s %s' % (self.col1, self.col3) # Notice I'm omitting col2.

当您调用__unicode__时,您的模型已经在内存中。您可以根据需要访问self中的字段,此时无法访问数据库。