django - 如何使用 ToManyField 加快 Tastypie 的查询速度

标签 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'

大约有 6 个类别的 5000 个项目。当我发出“列表”api 请求,即“api/1.0/category”时,它会对数据库进行大约 5000 次查询。我该如何优化它?我知道 full=False,但它不适合我的需要。

更新:
我发现是什么引起了如此多的查询。我在 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]

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

最佳答案

尝试这个:

def get_object_list(self, request):
    return super(CategoryResource, self).get_object_list(request) \
        .prefetch_related('items', 'items__categories')

请勿使用 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]

关于django - 如何使用 ToManyField 加快 Tastypie 的查询速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34841379/

相关文章:

python - Django - 默认端口 0 而不是 3306 - 无法连接到 '127.0.0.1' 上的 MySQL 服务器 (61)

python - 覆盖 clean(),数据不可访问

optimization - 车辆路径问题的 Pyomo 随机优化

algorithm - 二维最大子数组

django - 使用外键创建 tastypie 资源而不将外键公开为资源

django - 字段不允许过滤(未使用关系)

python - 无法让 ToMany 在 Tastypie 中工作

python - 在 Windows 上使用 cygwin for django serevr 安装 mysqlclient 因 gcc 错误而失败

django - Apple 使用 allauth 和 rest-auth 在 django rest 框架中登录

java - Objective C 相当于 java 中的 intern()