Django 3.2 как исправить ошибку AttributeError: 'itertools.chain' object has no attribute 'filter'?
У меня есть 3 набора запросов, которые мне нужно объединить и использовать метод filter
, когда пользователь выбирает флажок. Ajax работает нормально, но я испытываю трудности с отображением отфильтрованных данных, потому что получаю эту ошибку:
AttributeError: 'itertools.chain' object has no attribute 'filter'
Когда я пытаюсь выполнить итерацию над 1 моделью следующим образом favourite_list=Product.objects.all()
все работает нормально, но в моем случае мне нужно отфильтровать данные из 3 различных моделей
Я пытался использовать list(chain(fa, fv, fp))
, но это дает мне list object has no attribute filter
ошибку.
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})
Мой вопрос в том, как я могу исправить эту ошибку? Как я должен объединить fa, fv, pd
, чтобы они вели себя как нормальные наборы запросов и я мог использовать метод filter
на них.
filter предназначен для объектов с типом QuerySet, поэтому вы не можете использовать его на списке и цепочке.
Вместо этого вы можете сгруппировать избранные объекты после фильтрации
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})
и нет необходимости снова использовать distinct после условий, это уже было сделано один раз
Ну, похоже, что QuerySet.union()
это то, что вы ищете.
favourite_list = fa.union(fv, fp)
Что касается вашего первоначального вопроса, ни у типов list
, ни у intertools.chain
(который является типом, возвращаемым itertools.chain()
) нет метода filter()
, отсюда и ошибки.
>>> chain(["a"], ["b"])
<itertools.chain object at 0x7fd3f0a86580>