假设我有以下设计
一个track
有一个song
,一个song
有一个singer
。
我希望该曲目也允许基于歌手姓名进行过滤。
因此,我需要track
模型提取singer
名称。我被过滤器卡住了。
我收到以下错误消息:
File ".../lib/python3.6/site-packages/django_filters/filterset.py", line 352, in get_filters
"%s" % ', '.join(undefined)
TypeError: 'Meta.fields' contains fields that are not defined on this FilterSet: singer
我从this那里听说过要使用__
,但我不知道如何应用。
这是代码
class TrackSerializer(MyModelSerializer):
singer = serializers.SerializerMethodField()
def get_singer(self, track): # Is there any shortcut?
song = Song.objects.get(id=track.song_id)
if song is not None:
return Channel.objects.get(id=song.singer_id).name
else:
return ''
class Meta:
model = Track
fields = (
'id',
'name',
'song',
'singer',
)
class TrackFilterSet(MyFilterSet):
singer = CharFilter(method='singer_filter')
song = RefineModelChoiceFilter(
queryset=Song.objects.all(),
refine_choices=lambda qs, keywords, request: qs.filter(name__icontains=keywords)
)
def singer_filter(self, queryset, name, value):
# print('queryset:', TrackSerializer(queryset, many=True))
return queryset.filter(**{
name: value, # ???????????
})
class Meta:
model = Track
fields = (
'singer',
'song',
)
class TrackViewSet(MyViewSet):
queryset = Track.objects.all()
serializer_class = TrackSerializer
filterset_fields = ('singer', 'song')
def filter_refine_choices_singer(self, qs, keywords, request):
return qs.filter(name__icontains=keywords)
def filter_refine_choices_song(self, qs, keywords, request):
return qs.filter(name__icontains=keywords)
答案 0 :(得分:1)
尝试将filterset_fields作为数组放在[]而不是()之间。
filterset_fields = ['singer', 'song']
答案 1 :(得分:0)
我认为方法singer_filter
应该是这样的:
def singer_filter(self, queryset, name, value):
return queryset.filter(song_id__singer_id__name_icontains=value)
我没有对此进行测试,但我认为除非禁止第三种关系__
,否则类似的事情应该起作用。在这里看看:
https://django-filter.readthedocs.io/en/master/ref/filters.html?highlight=method