-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 つの DB クエリだけで、このクラス メソッド内で col1 と col3 を取得するにはどうすればよいですか? とてもシンプルであるべきだと思うので、何かばかげたことをしているように感じます。

アップデート:

フィードバックに基づいて、テスト モデル、テスト フォームなどを作成し、何人かのユーザーが述べたことは正しいことを発見しました。ただし、実際のコード (複数のフォームを使用) では、__unicode__連結された値の列を返すようにメソッドを変更すると、SQL クエリの数が 601 から 34 に変更されました。その 1 行だけを変更しました。私のテストケースに基づいて、おそらく何か他のことが起こっていますが、繰り返しますが、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__メソッド呼び出しはメモリ内呼び出しとして発生します。個別の DB 呼び出しをトリガーしません。

于 2013-09-19T05:01:00.947 に答える
1

あなたの機能を見てみましょう:

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

を呼び出すときには__unicode__、すでにモデルがメモリに格納されています。好きなだけフィールドにアクセスできselfますが、この時点からデータベースへのアクセスはありません。

于 2013-09-19T05:44:33.020 に答える
1

こんなことしてるんだろうな

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

その後

print myModelInstance
>> "WhateverCol1is WhateverCol2is"

そのモデルインスタンスを取得する必要があるため、これは絶対に 1 つのデータベース呼び出しをトリガーします。これが何をするかget()で、オブジェクトをすぐに取得します。

col1フィールド宣言を省略したため、 orがフィールドまたは のcol3いずれかであると推測しているため、インスタンスをフェッチすると、フィールドが参照する行がフェッチされます。ManyToManyForeignKey

このように行われた QuerySet がある場合

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

それを繰り返し処理すると、それが評価され、n回のデータベース呼び出しが必要になります。

QuerySet は遅延型で、特定のことが起こったときにのみ評価 (つまり、データベースにアクセス) します。

  • QuerySet の反復処理
  • クエリセットのスライス
  • list()QuerySet での使用
  • 使用するlen()
  • 使用するrepr()
  • QuerySet のピクルまたはキャッシュ

クエリセットの詳細については、こちらをご覧ください

于 2013-09-19T05:23:31.070 に答える