Django-减少用于过滤查询集的样板并可能提高性能 [英] Django - Reducing the boilerplate for to filter the queryset and possibly improve performance

查看:35
本文介绍了Django-减少用于过滤查询集的样板并可能提高性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用模型管理器返回经过过滤的搜索查询集,但是目前该样板很长,如果能够找到一种减少样板并获得一些性能的方法,我将感到非常高兴.

I am using Model Manager to return a filtered search queryset but currently the boilerplate for that is quite long, I'd be glad if I could find a way to reduce the boilerplate as well as gain some performance.

目前,我正在这样做:

class ImageTagManager(models.Manager):
    def ordered_images(self):
        queryset = self.model.objects.order_by('id').all()
        return queryset

    def search(self, query_dict):

        if isinstance(query_dict, list):
            queryset = ImageTag.objects.filter(id__in=query_dict)
            if queryset is not None:
                return queryset
            else:
                return False

        # Initially getting all objects
        queryset_initial = ImageTag.objects.all()

        # copying queryset_initial to filter
        queryset = queryset_initial

        queryset = queryset.filter(company__iexact=query_dict['company']) if query_dict.get('company') not in (
            None, '') else queryset
        queryset = queryset.filter(accoff__iexact=query_dict['accoff']) if query_dict.get('accoff') not in (
            None, '') else queryset
        queryset = queryset.filter(section__iexact=query_dict['section']) if query_dict.get('section') not in (
            None, '') else queryset
        queryset = queryset.filter(docref__iexact=query_dict['docref']) if query_dict.get('docref') not in (
            None, '') else queryset

        start_date = query_dict.get('start_date')
        end_date = query_dict.get('end_date')

        if start_date not in (None, '') and end_date not in (None, '') and start_date < end_date:
            queryset = queryset.filter(start_date__range=(start_date, end_date))
        elif start_date not in (None, ''):
            queryset = queryset.filter(start_date__exact=start_date) if query_dict.get('docref') not in (
                None, '') else queryset

        queryset = queryset.filter(pagenum__iexact=query_dict['pagenum']) if query_dict.get('pagenum') not in (
            None, '') else queryset
        queryset = queryset.filter(refnum__iexact=query_dict['refnum']) if query_dict.get('refnum') not in (
            None, '') else queryset
        queryset = queryset.filter(pernum__iexact=query_dict['pernum']) if query_dict.get('pernum') not in (
            None, '') else queryset
        queryset = queryset.filter(attr1__iexact=query_dict['attr1']) if query_dict.get('attr1') not in (
            None, '') else queryset
        queryset = queryset.filter(attr2__iexact=query_dict['attr2']) if query_dict.get('attr2') not in (
            None, '') else queryset
        queryset = queryset.filter(attr3__iexact=query_dict['attr3']) if query_dict.get('attr3') not in (
            None, '') else queryset
        queryset = queryset.filter(attr4__iexact=query_dict['attr4']) if query_dict.get('attr4') not in (
            None, '') else queryset
        queryset = queryset.filter(attr5__iexact=query_dict['attr5']) if query_dict.get('attr5') not in (
            None, '') else queryset

        if len(query_dict.get('tags')) > 0:
            tags = query_dict['tags']
            queryset = queryset.filter(tags__name__in=[tags])

        if queryset != queryset_initial:
            return queryset
        else:
            return []

基本上,搜索的作用是首先获取所有记录,然后根据通过query_dict(Form)传递的搜索条件对其进行过滤.返回结果查询集.

Basically what the search does is it first grabs all the records and then filters it down according to the search criteria passed through query_dict (Form). The resultant queryset is returned.

推荐答案

鉴于@Endre双方的评论,我设法遍历了过滤条件,发现处理列表条件并单独处理它有点困难.我做到的方式是:

In light of @Endre Both's comment I managed to do a loop through the filter criteria, I found a little difficulty handling the list criteria and handled it separately, the way I did it is:

    def search(self, query_dict):

        searched_for = {}
        for key in query_dict:
            if query_dict[key] not in (None, ''):
                if isinstance(query_dict[key], list):
                    pass
                else:
                    searched_for[key] = query_dict[key]
                # print(key)

        # Initially getting all objects
        queryset_initial = ImageTag.objects.all()

        # filtering based on non list criteria
        queryset = queryset_initial.filter(**searched_for)

        # filtering based on list criteria
        if query_dict['tags'] not in (None, ''):
            if len(query_dict['tags']) > 0:
                queryset.filter(tags__name__in=query_dict['tags'])

        if queryset != queryset_initial:
            return queryset
        else:
            return []

如果有人有更好的方法,如果能与我分享,我将不胜感激.

If someone has even better way of doing it, I'd really appreciate if shared.

这篇关于Django-减少用于过滤查询集的样板并可能提高性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆