如何使用动态过滤器创建django查询集?
所以基本上我在Django有一个网站,它是一个店面,最终用户有三个过滤器可以使用。产品类型过滤器(裤子、鞋子、衬衫等)、交付过滤器(是/否)和位置/人气过滤器 目前在my views.py中,我有这个方法如何使用动态过滤器创建django查询集?,django,django-views,Django,Django Views,所以基本上我在Django有一个网站,它是一个店面,最终用户有三个过滤器可以使用。产品类型过滤器(裤子、鞋子、衬衫等)、交付过滤器(是/否)和位置/人气过滤器 目前在my views.py中,我有这个方法 if request.is_ajax(): if request.GET.get('filter') == 'shirts': latest_entries = Entry.objects.filter(entrytype="shirts") conte
if request.is_ajax():
if request.GET.get('filter') == 'shirts':
latest_entries = Entry.objects.filter(entrytype="shirts")
context = {'latest_entries': latest_entries}
return render(request, 'storefrontload.html', context)
if request.GET.get('filter') == 'pants':
latest_entries = Entry.objects.filter(entrytype="pants")
context = {'latest_entries': latest_entries}
return render(request, 'storefrontload.html', context)
if request.GET.get('filter') == 'shoes':
latest_entries = Entry.objects.filter(entrytype="shoes")
context = {'latest_entries': latest_entries}
return render(request, 'storefrontload.html', context)
如您所见,这将处理第一个过滤器。我遇到的问题是,如果我选择,比如说“裤子”,它会按裤子过滤,但会忽略在其他两个过滤器中选择的内容。另一个例子,假设我选择了裤子,页面将填充该过滤器的结果。但是,如果我转到交付过滤器并选择“是”,页面将填充仅可交付的项目,但“裤子”过滤器将被遗忘
我想弄清楚的是如何在我的视图中创建一个能够记住其他两个查询集的查询集(如果有意义的话)
我能想到的唯一方法是为每个过滤器中的每个值创建真/假标志,然后添加大约100行if/then语句来检查每个标志。一定有更好的办法
更新:
这就是我如何从模板传递筛选值的方法
function filter(type) {
$.get("/storefront/?filter="+type, function(data) {
var $data = data;
$('.grid').children().remove();
$('.grid').append( $data ).masonry( 'appended', $data, true ).masonry( 'layout' );
});
}
//Product Filter
$("#shirts").unbind().click(function () {
filter("shirts");
return false;
});
$("#pants").unbind().click(function () {
filter("pants");
return false;
});
$("#shoes").unbind().click(function () {
filter("shoes");
return false;
});
//Delivery Filter
$("#deliveryyes").unbind().click(function () {
filter("deliveryyes");
return false;
});
$("#deliveryno").unbind().click(function () {
filter("deliveryno");
return false;
});
在my views.py中,这将不起作用:
entry_types = request.GET.getlist('filter')
latest_entries = Entry.objects.filter(entrytype__in=entry_types)
因为我需要按entrytype(‘裤子’、‘衬衫’、‘鞋子’)和deliveryoption(‘deliveryyes’、‘deliveryno’)进行过滤。在我的模型中,每个过滤器都有自己的列
models.py
class Entry(models.Model):
headline= models.CharField(max_length=200,)
body_text = models.TextField()
author=models.ForeignKey(settings.AUTH_USER_MODEL, related_name='entryauthors')
pub_date=models.DateTimeField(auto_now_add=True)
zipcode =models.IntegerField(null=True, max_length=10)
!!! entrytype = models.CharField(null=True, max_length=10)
!!! deliveryoption=models.CharField(null=True, max_length=5)
一个参数在请求中多次出现是完全有效的。用于获取包含所有值的列表
http://example.com/?foo=12&foo=34
您可以传递以逗号分隔的
过滤器
值列表:
/mylist/filter=shirts,pants
然后使用查找获取条目:
或者使用QueryDict
的getlist()
方法:
/mylist/filter=shirts&filter=pants
使用相同的ORM调用:
entry_types = request.GET.getlist('filter')
latest_entries = Entry.objects.filter(entrytype__in=entry_types)
更新:要将多个类型传递给视图,请将它们保存在数组中,并使用join()
方法获取它们的逗号分隔字符串:
var types = []; // currently shown entry types
function filter(type) {
// add or remove the items from the grid
var index = types.indexOf(type);
if (index > -1) {
types.splice(index, 1); // remove the type from the list
} else {
types.push(type); // add the type to the filter
}
$.get("/storefront/?filter="+types.join(","), function(data) {
...
}
}
更新2:如果使用两个字段筛选查询集,则必须在视图中创建两个单独的列表:
filters = request.GET.getlist('filter')
entry_types = [f for f in filters if not f.startswith('delivery')]
delivery_types = [f for f in filters if f.startswith('delivery')]
latest_entries = Entry.objects.all()
if entry_types:
latest_entries = latest_entries.filter(entrytype__in=entry_types)
if delivery_types:
latest_entries = latest_entries.filter(deliverytype__in=delivery_types)
JavaScript代码将不需要任何改动就可以工作。首先,我不确定如何传递多个过滤器的值。我更新了我的帖子,并从模板中包含了一些代码。将数组中的类型列表保存在全局范围中,然后从
单击事件更改此数组。看到更新的答案。好的,我想我会按照你建议的路线走。我还有一个关于如何在javascript中添加/删除类型数组的问题。我马上会更新OP。好的,你能解释一下你上面发布的javascript吗?具体来说,当你点击鞋子时,我不知道如何从数组中删除过滤器,例如衬衫、裤子?此外,我更新了我的帖子,如果你看一下帖子的底部,你可以看到我的models.py我在数据库表中有单独的列,分别是“entrytype”和“deliveryoption”。这不是意味着Entry.objects.filter(entrytype\uuuu-in=Entry\u-types)不能工作吗?
var types = []; // currently shown entry types
function filter(type) {
// add or remove the items from the grid
var index = types.indexOf(type);
if (index > -1) {
types.splice(index, 1); // remove the type from the list
} else {
types.push(type); // add the type to the filter
}
$.get("/storefront/?filter="+types.join(","), function(data) {
...
}
}
filters = request.GET.getlist('filter')
entry_types = [f for f in filters if not f.startswith('delivery')]
delivery_types = [f for f in filters if f.startswith('delivery')]
latest_entries = Entry.objects.all()
if entry_types:
latest_entries = latest_entries.filter(entrytype__in=entry_types)
if delivery_types:
latest_entries = latest_entries.filter(deliverytype__in=delivery_types)