0

私は次のように設定されているdjangoモデルのセットを持っています:

class Foo(models.Model):
    ...

class FooVersion(models.Model):
    name = models.CharField(max_length=100)
    parent = models.ForeignKey(Foo)
    version = models.FloatField()
    ...

すべてのFooを最高バージョンの名前のアルファベット順に表示するDjangoListViewを作成しようとしています。たとえば、次のようなデータセットがある場合:

version_id | id |           version_name            | version 
-----------+----+-----------------------------------+---------
         1 | 1  | Test 1                            |      1.0
         2 | 1  | Test 2                            |      2.0
         3 | 1  | Test 2                            |      3.0
         4 | 2  | Test 1                            |      1.0
         5 | 1  | Test 3                            |      2.5
         6 | 3  | Test 3                            |      1.0

クエリが返されるようにしたい:

version_id | id |           version_name            | version 
-----------+----+-----------------------------------+---------
         4 | 2  | Test 1                            |      1.0
         3 | 1  | Test 2                            |      3.0
         6 | 3  | Test 3                            |      1.0

これを生成するために使用する生のSQLは次のとおりです。

SELECT version_class.id as version_id, someapp_foo.id, version_class.name as version_name, version_class.version
FROM someapp_foo
INNER JOIN(
    SELECT someapp_fooversion.name, someapp_fooversion.version, someapp_fooversion.parent_id, someapp_fooversion.id
    FROM someapp_fooversion
    INNER JOIN(
        SELECT parent_id, max(version) AS version
    FROM courses_courseversion GROUP BY parent_id)
AS current_version ON current_version.parent_id = someapp_fooversion.parent_id
AND current_version.version = someapp_fooversion.version)
AS version_class ON version_class.parent_id = someapp_foo.id
ORDER BY version_name;

しかし、RawQuerySetオブジェクトには、ページネーションのためにListViewによって呼び出される'count'メソッドがないため、rawクエリの使用に問題があります。Djangoクエリセットの「追加」機能を調べましたが、それで機能するクエリを作成するのに問題があります。

探しているものを取得する「extra」のクエリをどのように作成しますか?または、RawQuerySetを通常のQuerySetに変換する方法はありますか?私が探している結果を得るための他の可能な解決策はありますか?

4

3 に答える 3

0

これを行うためのより良い方法があるかもしれませんが、今のところ、うまくいくと思われるカスタムソリューションを試しています:

from django.db import models
from django.db.models.query import RawQuerySet

class CountableRawQuerySet(RawQuerySet):
   def count(self):
       return sum([1 for obj in self])

class FooManager(models.Manager):
    def raw(self, raw_query, params=None, *args, **kwargs):
        return CountableRawQuerySet(raw_query=raw_query, model=self.model, params=params, using=self._db, *args, **kwargs)

class Foo(models.Model):
    objects = FooManager()

次に、私のクエリセットは次のとおりです。

Foo.objects.raw(sql)

これを改善する方法についての提案はありますか?

于 2012-08-14T19:46:49.173 に答える
0

まず第一に、あなたのソリューションは間違っており、大量のデータに対して非常に効果的ではありません. 次のようなものが必要だと思います:

from django.db.models import Max
Foo.objects.annotate(max_version=Max(fooversion__version))

max_version通常の属性と同じように、各結果の属性を参照できるようになりました。詳細については、 https://docs.djangoproject.com/en/dev/topics/db/aggregation/を参照してください。

于 2012-08-14T22:37:47.553 に答える