0

假设我有一个“查找发票页面”,用户可以在其中输入(或不输入)不同的字段,以便搜索发票以在列表中显示它们。假设这个字段列表可能会随着时间的推移增加额外的 db 字段。我当前的(工作)解决方案如下,但我想知道是否有更好的方法来允许可能的附加字段并相应地调整查询。

query.py [自定义查询编写器]

from .models import Invoice

class FindQuery:

    def __init__(self):
        self.filters = {}
        self.fq_sql = ''
        self.fq_select = 'SELECT * '
        self.fq_from = 'FROM invoice_invoice '
        self.fq_where = 'WHERE 1=1 '
        self.fq_order = ' ORDER BY iv_created_at DESC'

    def set_filters(self, user, year, client):
        if user:
            self.filters['request_user'] = user

        if year:
            self.filters['selected_year'] = year

        if client:
            self.filters['selected_client'] = client

        # adding here new fields
    
    def apply_filter(self):

        if 'request_user' in self.filters:
            self.fq_where += ' AND iv_created_by = ' + str(self.filters.get('request_user'))

        if 'selected_year' in self.filters:
            self.fq_where += ' AND iv_year = ' + str(self.filters.get('selected_year'))
            
        if 'selected_client' in self.filters:
            self.fq_where += ' AND iv_client = ' + str(self.filters.get('selected_client'))

        # adding here new fields

        self.fq_sql = self.fq_select + self.fq_from + self.fq_where + self.fq_order
        return Invoice.objects.raw(self.fq_sql)

views.py(Django 休息框架)

from .query import FindQuery

class InvoiceViewSet(viewsets.ModelViewSet):
    serializer_class = InvoiceSerializer


    def get_queryset(self):
        q = FindQuery()

        user = self.request.user.id
        year = self.request.GET.get('selected_year')
        client = self.request.GET.get('selected_client')
        # adding here new fields

        q.set_filters(user, year, client)
        qs = q.apply_filter()
        result = Invoice.objects.filter(iv_id__in=[q.iv_id for q in qs])
        return result
4

1 回答 1

0

这里是使用 ORM 方法的解决方案。短而快!还解决了附加/可选搜索字段的问题。

class InvoiceViewSet(viewsets.ModelViewSet):
    serializer_class = InvoiceSerializer

    def get_queryset(self):
        
        # input value from search page
        user = self.request.user.id
        year = self.request.GET.get('selected_year')
        client = self.request.GET.get('selected_client')

        filters = {
            # model name: input value
        }

        if user:
            filters['iv_created_by'] = user

        if year:
            filters['iv_year'] = year

        if client:
            filters['iv_client'] = client

        result = Invoice.objects.filter(**filters)

        return result
于 2021-03-11T12:00:32.927 回答