基于填充GET请求键的Django动态搜索视图

2024-05-29 04:24:33 发布

您现在位置:Python中文网/ 问答频道 /正文

请问在Django中,如何能够访问一个视图,该视图将根据GET请求中的填充键进行过滤

我只使用一个搜索视图,但使用两种形式:

form1 and form2

我接受这些要求:

q = request.GET.get('q') # this is for VIN and LOT number (two columns in Model/DB)
make = request.GET.get('make')
model = request.GET.get('model')
year_from = request.GET.get('year_from')
year_to = request.GET.get('year_from')

没有必需的字段/请求,因此它应该动态工作。如果用户填写“q”-它将按VIN或批号过滤掉。 如果用户将填写品牌和年份,它将按品牌和年份过滤掉

如果,elif,elif,elif,…有什么合适的方法吗

这是我的解决方案,但我真的不喜欢它,它不专业,我不知道如何找到更好的解决方案

def is_valid_queryparam(param):
    return param != '' and param is not None


def search_filer(request):
    qs = Vehicle.objects.all()

    # VIN and Lot number
    q = request.GET.get('q')

    make = request.GET.get('make')
    model = request.GET.get('model')
    year_from = request.GET.get('year_from')
    year_to = request.GET.get('year_from')

    if is_valid_queryparam(q):
        qs = qs.filter(Q(vin__icontains=q) | Q(lot_number__icontains=q))

    elif is_valid_queryparam(make):
        qs = qs.filter(make__name__exact=make)

    elif is_valid_queryparam(model):
        qs = qs.filter(model__name__exact=model)

    elif is_valid_queryparam(year_from):
        qs = qs.filter(year__gte=year_from)

    elif is_valid_queryparam(year_to):
        qs = qs.filter(year__lte=year_to)

    elif is_valid_queryparam(make) and is_valid_queryparam(model):
        qs = qs.filter(make__name__exact=make)\
               .filter(model__name__exact=model)

    elif is_valid_queryparam(make) and is_valid_queryparam(model) and is_valid_queryparam(year_from):
        qs = qs.filter(make__name__exact=make)\
               .filter(model__name__exact=model)\
               .filter(year__gte=year_from)

    elif is_valid_queryparam(make) and is_valid_queryparam(model)\
            and is_valid_queryparam(year_from) and is_valid_queryparam(year_to):
        qs = qs.filter(make__name__exact=make)\
               .filter(model__name__exact=model)\
               .filter(year__gte=year_from)\
               .filter(year__lte=year_to)
        
        ...
        ...
        ...

    return qs


def search_view(request):
    qs = search_filer(request)

    # Year field for search form
    today = datetime.now()

    context = {
        'queryset': qs,
        'years_from': reversed(range(1920, today.year + 1)),
        'years_to': reversed(range(1920, today.year + 1))
    }

    return render(request, 'search.html', context)

谢谢你的建议


我也不知道为什么上下文不能重用,正如你所看到的,我创建了两个变量years\u fromyears\u to,因为我在模板中循环使用它们:

<option value>From ...</option>
{% for y in years_from %}
    <option value="{{ y }}">{{ y }}</option>
{% endfor %}

<option value>To ...</option>
{% for y in years_to %}
    <option value="{{ y }}">{{ y }}</option>
{% endfor %}

当我尝试只创建一个一年变量并在模板中循环时,它起了作用。但是当我用相同的变量创建另一个循环时,没有显示任何值。所以我创建了完全相同的变量和循环

多谢各位


Tags: andtofromgetmakemodelisrequest
1条回答
网友
1楼 · 发布于 2024-05-29 04:24:33

我已经想出了解决这个问题的办法。它确实不专业,但它做了理想的工作。我将很高兴得到任何建议或提示,以使我的代码更好。如果有人想尝试像我这样的东西,我的解决方案如下:

def is_valid_queryparam(param):
    return param != '' and param is not None


def is_valid_name(name):
    return name == 'make' or name == 'model' or name == 'year_from' or name == 'year_to'


def get_filter(key):
    if key == 'make':
        return 'make__name__exact'
    if key == 'model':
        return 'model__name__exact'
    if key == 'year_from':
        return 'year__gte'
    if key == 'year_to':
        return'year__lte'


def search_view(request):
    queryset = None
    valid_params = False

    # VIN and LOT number
    q = request.GET.get('q')

    if is_valid_queryparam(q):
        queryset = Vehicle.objects.filter(Q(vin__icontains=q) | Q(lot_number__icontains=q))
    else:
        request_filter = {}
        q_list = Q()
        for key, value in request.GET.items():
            if is_valid_name(key) and is_valid_queryparam(value):
                valid_params = True
                request_filter[get_filter(key)] = value
        if valid_params:
            for k, v in request_filter.items():
                q_list.add(Q(**{k: v}), Q.AND)

            queryset = Vehicle.objects.filter(q_list)

    # Year field for search form
    today = datetime.now()
    years_from = reversed(range(1920, today.year + 1))
    years_to = reversed(range(1920, today.year + 1))

    context = {
        'queryset': queryset,
        'years_from': years_from,
        'years_to': years_to
    }
    return render(request, 'search.html', context)

相关问题 更多 >

    热门问题