Issue
I have 3 querysets that I need to merge and use filter
method when the user selects a checkbox. Ajax works fine but I am struggling with displaying filtered data because I am getting this error:
AttributeError: 'itertools.chain' object has no attribute 'filter'
When I am trying to iterate over 1 model like this favourite_list=Product.objects.all()
everything works fine but in my case, I need to filter data from 3 different models.
I tried to use list(chain(fa, fv, fp))
but it gives me list object has no attribute filter
error.
def filter_favourites(request):
favourite_articles = request.GET.getlist('favourite_articles[]')
favourite_video = request.GET.getlist('favourite_video[]')
favourite_product = request.GET.getlist('favourite_product[]')
fa = request.user.favourite_article.all().distinct() #list of favourites items from Article model
fv = request.user.favourite_video.all().distinct() #list of favourites items from Video model
fp = request.user.favourite_product.all().distinct() #list of favourites items from Product model
favourite_list = chain(fa, fv, fp)
if len(favourite_articles) > 0:
favourite_list = favourite_list.filter(title__in=favourite_articles).distinct()
if len(favourite_video) > 0:
favourite_list = favourite_list.filter(title__in=favourite_video).distinct()
if len(favourite_product) > 0:
favourite_list = favourite_list.filter(title__in=favourite_product).distinct()
context = {
'combined_queryset': favourite_list,
}
ajax_template = render_to_string('user/user_favourites_ajax.html', context)
return JsonResponse({'data': ajax_template})
My question is how can I fix this error? How should I merge fa, fv, pd
so they behave like normal querysets and I can use filter
method on them.
Solution
filter method is for objects with type of QuerySet, so you can't use it on list and chain.
instead you can group the favourites after filtering
def filter_favourites(request):
favourite_articles = request.GET.getlist('favourite_articles[]')
favourite_video = request.GET.getlist('favourite_video[]')
favourite_product = request.GET.getlist('favourite_product[]')
fa = request.user.favourite_article.all().distinct() #list of favourites items from Article model
fv = request.user.favourite_video.all().distinct() #list of favourites items from Video model
fp = request.user.favourite_product.all().distinct() #list of favourites items from Product model
if len(favourite_articles) > 0:
fa = fa.filter(title__in=favourite_articles)
if len(favourite_video) > 0:
fv = fv.filter(title__in=favourite_video)
if len(favourite_product) > 0:
fp = fp.filter(title__in=favourite_product)
favourite_list = chain(fa, fv, fp)
context = {
'combined_queryset': favourite_list,
}
ajax_template = render_to_string('user/user_favourites_ajax.html', context)
return JsonResponse({'data': ajax_template})
and no need to use distinct again after conditions, it has done once before
edited:
def filter_favourites(request):
favourite_articles = request.GET.getlist('favourite_articles[]')
favourite_video = request.GET.getlist('favourite_video[]')
favourite_product = request.GET.getlist('favourite_product[]')
favourite_titles = favourite_articles + favourite_video + favourite_product
favourites_items_list = [
request.user.favourite_article.all().distinct(), #list of favourites items from Article model
request.user.favourite_video.all().distinct(), #list of favourites items from Video model
request.user.favourite_product.all().distinct(), #list of favourites items from Product model
]
if len(favourite_titles) > 0:
for ind, f in enumerate(favourites_items_list):
favourites_items_list[ind] = f.filter(title__in=favourite_titles)
favourite_list = chain(*favourites_items_list)
context = {
'combined_queryset': favourite_list,
}
ajax_template = render_to_string('user/user_favourites_ajax.html', context)
return JsonResponse({'data': ajax_template})
Answered By - Amrez
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.