1

クロステーブル (MovieGenre) を使用して多対多の関係で接続されている 2 つのテーブル (Movie と Genre) があります。

私の models.py ファイルは次のようになります。

class Genre( models.Model ):

    sName = models.CharField( max_length=176)
    [ .. ]

class Movie( models.Model ):

    sTitle = models.CharField( max_length=176)
    genre = models.ManyToManyField( Genre )
    [ .. ]

class MovieGenre( models.Model ):

    idMovie = models.ForeignKey( Movie )
    idGenre = models.ForeignKey( Genre )

Tastypie を使用して、特定のジャンルのすべての映画をフィルター処理したいと考えています。たとえば、ジャンルがアクション、スリラー、SF のすべての映画を表示します。

私の api.py は次のようになります。

class GenreResource(ModelResource):
    class Meta:
        queryset = Genre.objects.all()
        resource_name = 'genre'
        always_return_data = True
        include_resource_uri = False
        excludes = ['dtCreated', 'dtModified' ]
        authorization= Authorization()
        authentication = SessionAuthentication()
        filtering = {
            "id" : ALL,
        }


class MovieResource(ModelResource):
    genre = fields.ManyToManyField( 'app.api.GenreResource', 'genre', full=True )
    class Meta:
        queryset = Movie.objects.all()
        resource_name = 'movie'
        authorization= Authorization()
        authentication = SessionAuthentication()
        always_return_data = True
        include_resource_uri = False
        excludes = ['dtCreated', 'dtModified' ]
        filtering = {
            "sTitle" : ALL,
            "genre" : ALL_WITH_RELATIONS,
        }

テスト データ: 2 つの映画 (ジャンル ID 付き) マトリックス (1 & 3) ブレード ランナー (1 & 2)

最初に、タイトルに対してクエリを作成します。次のクエリでは、1 つの結果 (つまり、Matrix) が返されます。

   http://localhost:8000/api/v1/movie/?format=json&sTitle__icontains=a&sTitle__icontains=x

ただし、次のクエリを使用して、関連するジャンル テーブル (2 回はマトリックス、1 回はブレード ランナー) をクエリする必要がある URL で 3 つの結果を取得します。

    http://localhost:8000/api/v1/movie/?format=json&genre__id__in=3&genre__id__in=1

マトリックスだけが返ってくると思います

また、次のように apply_filters をオーバーライドしようとしました。

def apply_filters(self, request, applicable_filters):
    oList = super(ModelResource, self).apply_filters(request, applicable_filters)
    loQ = [Q(**{'sTitle__icontains': 'a'}), Q(**{'sTitle__icontains': 'x'})]
    # works as intended: one result
    loQ = [Q(**{'genre__id__in': '3'}) ]
    # results in one result (Matrix)

    loQ = [Q(**{'genre__id__in': '1'}), Q(**{'genre__id__in': '3'}) ]
    # results in no results!

    loQ = [Q(**{'genre__id__in': [ 1, 3]}) ]
    # results in two results Matrix and Blade Runner which is OK since obviously ORed
    oFilter = reduce( operator.and_, loQ )
    oList = oList.filter( oFilter ).distinct()
    return oList

これを機能させるためのアイデアはありますか?

アイデアをありがとう...

4

1 に答える 1

3

やってみましたhttp://localhost:8000/api/v1/movie/?format=json&genre__id=3&genre__id=1

私の理解が正しければ、__inそのように使用することは、 と言うようなものgenre__id__in=[1, 3]です。

于 2013-02-28T16:43:40.977 に答える