エラー Related Field got invalid lookup: icontains が DRF SearchFilter で出た場合の対応

- アーティスト: O.S.T.
- 出版社/メーカー: Universal
- 発売日: 2017/04/07
- メディア: CD
- この商品を含むブログを見る
症状
#model
class Hoge(models.Model):
hoge_name = models.CharField(max_length=300, blank=True, null=True)
first_category = models.ManyToManyField(HogeCategory, blank=True)
というモデルをDRFのListAPIViewでとってきたいとする。フィルターをかけたいものが2つ以上あるので、search_fields(?search=で検索できるようになるもの)と別途q=でフィルターもかけられるようにした。
#api.views
class HogeListAPIView(ListAPIView):
permission_classes = [AllowAny]
queryset = Hoge.objects.all()
serializer_class = HogeListSerializer
filter_backends= [SearchFilter] #
search_fields = ['first_category__id'] #['first_category']でも同じエラー出る
def get_queryset(self, *args, **kwargs):
queryset_list = Hoge.objects.all()
query_f = self.request.GET.get("f")
if query_f:
queryset_list = queryset_list.filter(
Q(hoge_name__icontains=query_f)
).distinct()
return queryset_list
このようにした場合、エラ−になり、エラーメッセージはRelated Field got invalid lookup: icontains
と出た。試行錯誤実験をして挙動を確認したところ、
SearchFilterの場合、ForeignKeyのフィールドはすべてのフィールドで、search_fields = ['first_category__id']のようにSearchFilterの対象にすると、同じRelated Field got invalid lookup: icontainsエラーがでたので、以下のようにすることでエラー回避ができる。
解決策
うまく行ったパターン
class HogeListAPIView(ListAPIView):
permission_classes = [AllowAny]
queryset = Hoge.objects.all()
serializer_class = HogeListSerializer
filter_backends= [SearchFilter]
search_fields = ['hoge_name'] #ForeignKey以外のフィールドを対象にする
pagination_class = LimitOffsetPagination
def get_queryset(self, *args, **kwargs):
queryset_list = Hoge.objects.all()
query_f = self.request.GET.get("f") #ForeignKeyのフィルタリングは、get_querysetのオーバーライドで対応
if query_f:
queryset_list = queryset_list.filter(
Q(first_category__id__contains=query_f)
).distinct()
return queryset_list
参考記事(ダイレクトに同じ症状ではないけどもヒントにはなった)