我有一个标签数组作为模型字段,我想根据这些数组元素过滤掉。这里是标记字段是我猜的数组类型的模型。
class Mineral(models.Model):
name=models.CharField(max_length=500)
tags=TaggableManager()
def __unicode__(self):
return self.name
现在在我看来,我想基于此标记字段过滤掉 我可以像这样使用Django这样做
class MineralList(APIView):
queryset = Mineral.objects.all()
serializer_class = MineralSerializer
permission_classes = [AllowAny]
def get(self, request, format=None):
mineral = Mineral.objects.all()
tags = request.query_params.get('tags', None)
name= request.query_params.get('name',None)
if tags is not None:
tags = tags.split(',')
mineral = mineral.filter(tags__name__in=tags).distinct()
if name:
mineral = mineral.filter(name=name)
serializer = MineralSerializer(mineral, many=True)
return Response(serializer.data)
如何使用过滤后端和过滤器类
以REST方式执行此操作答案 0 :(得分:1)
您可以像这样创建FilterSet类:
from django_filters.rest_framework import FilterSet, filters
from django_filters.widgets import CSVWidget
class MineralFilterSet(FilterSet):
tags = filters.CharFilter(distinct=True, widget=CSVWidget, method='filter_tags')
name = filters.CharFilter()
class Meta:
model = Mineral
fields = ['name', 'tags']
def filter_tags(self, queryset, name, value):
return queryset.filter(tags__name__in=value)
你的观点应该是这样的:
from django_filters.rest_framework import DjangoFilterBackend
class MineralList(ListAPIView):
queryset = Mineral.objects.all()
serializer_class = MineralSerializer
permission_classes = [AllowAny]
filter_backends = (DjangoFilterBackend,)
filter_class = MineralFilterSet
答案 1 :(得分:1)
我很难得到加百利的答案,所以如果其他任何人都面临这个问题,这对我来说很有效。
过滤器:
from django_filters.rest_framework import FilterSet, filters
from django_filters.widgets import CSVWidget
from .models import Contact
class ContactFilter(FilterSet):
tags = filters.BaseCSVFilter(
distinct=True, widget=CSVWidget(), method="filter_tags"
)
class Meta:
model = Contact
@staticmethod
def filter_tags(queryset, field_name, value):
return queryset.filter(tags__name__in=value)
ViewSet:
from django_filters.rest_framework import DjangoFilterBackend
class ContactViewSet(ModelViewSet):
queryset = Contact.objects.all()
serializer_class = ContactSerializer
filter_backends = (DjangoFilterBackend,)
filter_class = ContactFilter
重要的部分是使用BaseCSVFilter而不是CharFilter,否则CSVWidget将吐出列表的字符串,而不是列表。