Django如何在__gt和__range之间动态选择

时间:2014-04-23 08:00:31

标签: python django django-models django-forms django-templates

我的django模板中有一个html表单,用户可以选择对象价格的范围以及实际价格的范围。但他不需要。

<select name="minimum_price">
    <option value="1">1</option>
    <option value="2">2</option>
</select>

<select name="maximum_price">
    <option value="1">1</option>
    <option value="2">2</option>
</select>

<select name="min_real_value">
    <option value="1">1</option>
    <option value="2">2</option>
</select>

<select name="max_real_value">
    <option value="1">1</option>
    <option value="2">2</option>
</select>

我已经阅读了django的大部分文档,包括以下有启发性的文章:Q Class。但是我还没有弄清楚如何为我的模型动态构建查询,因为用户可以从这4个选择框中选择任何可能的组合。

当只选择每个'类别'中的一个选择框时,Django的__range必须替换为__gt__lt,才会出现真正的问题。

这是我到目前为止所做的:

myList = MyObjectsCost.objects.filter(price__range=(minimum_price, maximum_price),
                                   real_value__range=(min_real_value, max_real_value),
                                   **kwargs)

然而,如果缺少4个变量中的一个,则会失败...

提前致谢。

2 个答案:

答案 0 :(得分:1)

你可以在这里使用kwargs做一些聪明的事情,但如果你只是反映出range只是gtlt的组合,那可能会更容易。所以你可以动态地构建查询:

my_list = MyObjectsCost.objects.all()
if minimum_price:
    my_list.filter(price__gt=minimum_price)
if maximum_price:
    my_list.filter(price__lt=maximum_price)
if min_real_value:
    my_list.filter(real_value__gt=min_real_value)
if max_real_value:
    my_list.filter(real_value__lt=max_real_value)

答案 1 :(得分:1)

&#34;聪明&#34;丹尼尔罗斯曼所说的是,用字符串构造过滤器,我假设?

它是这样的:

method = MyObjectsCost.objects.filter
qs = method(**{'%s__%s' % (field_name, lookup_type): value})

为您的情况提供正确的价值观,您可以建立以下内容:

field_name = 'real_value'
lookup_type = 'gt'
value = 'min_real_value'

将构建一个&#39; real_value__gt=min_real_value&#39;传递给filter方法的字符串。因此,您可以基于字符串创建过滤器。这可以派上用场,但也可能最终成为难看的hacky代码。因此请谨慎使用,但这个概念可以帮助您构建过滤器。

如果您喜欢第三方应用,请查看https://github.com/alex/django-filter,这样您也可以更灵活地使用过滤器。

但永远不要忘记保持简单。