Django - 根据多对多关系获得查询结果

时间:2016-02-07 21:52:56

标签: python django django-queryset

通过URI GET给出以下模型和字符串数组,如何有效地执行过滤操作并返回所有Trail匹配?

class Trail(models.Model):
    '''
    Main model for this application.  Contains all information for a particular trail
    '''
    trail_name = models.CharField(max_length=150)
    active = models.BooleanField(default=True)
    date_uploaded = models.DateTimeField(default=now())
    owner = models.ForeignKey(Account, default=1)

class Surface(models.Model):
    '''
    A many to many join table to map a surface type to many trails.  A trail can have many
    surface types.
    '''
    type = models.CharField(max_length=50, db_column='surface_type', unique=True)
    trails = models.ManyToManyField(Trail)

    class Meta:
        ordering = ('type', )

天真地,我可以获得所有的Trail模型并迭代它们来获得匹配,但是想要一种更有效的方式。

我试图这样做:

from django.models.db import Q

#List of strings as a result of a URL querystring like
#?keys=Dirt&keys=Gravel&keys=Paved
keys = request.GET.getlist('keys')

queries = [Q(type = surface) for surface in keys]
query = queries.pop()

for item in queries:
     query |= item

results = Trail.objects.filter(surface=type)

但这会返回ValueError: invalid literal for int() with base 10:例外。

1 个答案:

答案 0 :(得分:2)

这里根本不需要使用Q。您可能拥有的是与Surface对象的type字段对应的字符串列表,并且您希望获得与这些Surface相关的Trails。您可以使用__in查询多个曲面类型,也可以使用双下划线关系来跨越Surface和Trail之间的关系。所以:

Trail.objects.filter(surface__type__in=request.GET.getlist('keys'))