-1

这似乎是我忽略的一些简单的事情,但无论如何都是这样。

我定义了一个模型,我想从模型中检索某些列(不是通过 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 个 DB 查询。如何仅在 1 个数据库查询中检索此类方法中的 col1 和 col3?似乎它应该如此简单,以至于我觉得我在做一些愚蠢的事情。

更新:

根据反馈,我创建了一个测试模型,测试表格等......并发现几个用户所说的都是正确的。但是,在我的实际代码中(使用多个表单),更改__unicode__方法以返回一列连接值将 SQL 查询的数量从 601 更改为 34。我只更改了那一行。根据我的测试用例,也许还有其他事情正在发生,但重申一下,我只更改了 unicode 方法,我得到的 DB 命中数量完全不同。

我不确定我的其他代码发生了什么,我将不得不尝试仔细查看它。同时这里是测试用例,证明你们是正确的:

# 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)
4

3 回答 3

1

__unicode__方法调用是作为内存调用发生的。它不会触发单独的数据库调用。

于 2013-09-19T05:01:00.947 回答
1

我猜你正在这样做

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

接着

print myModelInstance
>> "WhateverCol1is WhateverCol2is"

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

由于您省略了字段声明,我猜测col1orcol3ManyToMany字段或 a ForeignKey,因此在获取实例时它将获取字段引用的行。

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

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

并对其进行迭代,它将评估它并需要n 次数据库调用。

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

  • 遍历查询集
  • 切片查询集
  • list()在查询集上使用
  • 使用len()
  • 使用repr()
  • 酸洗或缓存 QuerySet

在此处阅读有关QuerySet的更多信息

于 2013-09-19T05:23:31.070 回答
1

让我们看看你的功能:

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

当您调用__unicode__时,您的模型已经在内存中了。您可以随心所欲地访问这些字段,self此时没有数据库访问权限。

于 2013-09-19T05:44:33.020 回答