如何使用ToManyField加速tastypie的查询

svf*_*fat 10 django optimization tastypie

在resources.py我有:

class CategoryResource(ModelResource):
    items = fields.ToManyField('ItemResource', 'items', full=True, null=False, readonly=True, related_name='items')
    class Meta:
        queryset = Category.objects.all().order_by('id')
        include_resource_uri = False
        always_return_data = True
        resource_name = 'category'
Run Code Online (Sandbox Code Playgroud)

6类中约有5000种.当我制作'list'api请求即'api/1.0/category'时,它会对数据库进行大约5000次查询.我该如何优化它?我知道full = False,但它不适合我的需要.

UPD: 我发现了导致如此多查询的原因.我在ItemResource中有'类别'关系,因此tastypie为每个项生成一个选择查询.

class ItemResource(ModelResource):
    categories = fields.ToManyField(CategoryResource, 'categories', null=True, readonly=True)

    def dehydrate_categories(self, bundle):
        categories = Category.objects.filter(owner_id=bundle.request.user.id, items__item=bundle.obj)
        return [category.name for category in categories]
Run Code Online (Sandbox Code Playgroud)

当我请求CategoryResource时,显然这是不必要的数据,有没有办法将它从查询中排除?

Tom*_*Rup 4

尝试这个:

def get_object_list(self, request):
    return super(CategoryResource, self).get_object_list(request) \
        .prefetch_related('items', 'items__categories')
Run Code Online (Sandbox Code Playgroud)

不要使用select_related,因为它会返回重复的行。

prefetch_related做了一个查询,返回所有项目,Django ORM 将其匹配到正确的行。

编辑

改变dehydrate_categories

def dehydrate_categories(self, bundle):
    return [category.name for category in bundle.obj.categories.all() if category.owner == bundle.request.user]
Run Code Online (Sandbox Code Playgroud)