Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django tastypie:使用多个AND值筛选多对多表_Django_Filter_Tastypie_Relation_M2m - Fatal编程技术网

Django tastypie:使用多个AND值筛选多对多表

Django tastypie:使用多个AND值筛选多对多表,django,filter,tastypie,relation,m2m,Django,Filter,Tastypie,Relation,M2m,我有两个表(电影和流派),它们使用交叉表(电影流派)通过多对多关系连接起来 我的models.py文件如下所示: class Genre( models.Model ): sName = models.CharField( max_length=176) [ .. ] class Movie( models.Model ): sTitle = models.CharField( max_length=176) genre = models.ManyToMan

我有两个表(电影和流派),它们使用交叉表(电影流派)通过多对多关系连接起来

我的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 )
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,
        }
我想使用tastypie来过滤特定类型的所有电影。例如,给我看所有类型动作片、惊悚片和科幻片

我的api.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 )
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,
        }
我的测试数据: 两部电影(带有流派ID) 矩阵(1和3) 叶片转轮(1和2)

首先,我对标题进行查询,如下所示,查询返回1个结果(即矩阵):

但是,我通过URL得到了三个结果,该URL应通过此查询查询相关的流派表(两次矩阵和一次Blade Runner):

    http://localhost:8000/api/v1/movie/?format=json&genre__id__in=3&genre__id__in=1
我只希望能得到矩阵

我还尝试覆盖apply_过滤器,如下所示:

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
有什么办法让这一切顺利吗


谢谢你的建议…

你试过
http://localhost:8000/api/v1/movie/?format=json&genre__id=3&genre__id=1


如果我理解正确,那么用
\uu in
这种方式就像说
类型id\uuu in=[1,3]

我不得不同意。在中使用
\u时,它将返回该列表中包含id的任何结果,如第三个
应用过滤器
示例所示。@msc的解决方案的替代方案也可以是使用
genre\uu id\uu-exact
genre\uu-pk
。genre\uu-id=1与genre\uu-id\uu-exact=1相同。是的,只是提供了替代语法。从技术上讲,我应该说
体裁\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu谢谢你的提示,使用genre\uuuuu id,genre\uuuu id\uuuuuuu-exact为URL实现了这个技巧。伟大的但是仍然存在一个问题,如果我想用q对象创建过滤器,我在与上面示例中的两个“流派id”对象进行ANDing时仍然没有结果。。。知道为什么吗?一个有效的方法是链接过滤器,比如:oList=oList.filter(oFilter_1)、filter(oFilter_2)。。。但不知何故,我不确定为什么在
apply\u filters
方法中会使查询变得如此复杂。例如,您可以使用这个
oList=oList.filter(sTitle\u icontains='a',而不是类似于:
loQ=[Q(**{'sTitle\u icontains':'a',Q(**{'sTitle\u icontains':'x'})]