我正在尝试使用django REST设计灵活的API。我的意思是基本上可以通过查询字符串过滤任何字段,除此之外在查询字符串中有一个可以表示要执行的复杂方法的参数。好的,详情如下:
views.py
class StarsModelList(generics.ListAPIView):
queryset = StarsModel.objects.all()
serializer_class = StarsModelSerializer
filter_class = StarsModelFilter
serializers.py
class StarsModelSerializer(DynamicFieldsMixin, serializers.ModelSerializer):
class Meta:
model = StarsModel
fields = '__all__'
mixins.py
class DynamicFieldsMixin(object):
def __init__(self, *args, **kwargs):
super(DynamicFieldsMixin, self).__init__(*args, **kwargs)
fields = self.context['request'].query_params.get('fields')
if fields:
fields = fields.split(',')
# Drop any fields that are not specified in the `fields` argument.
allowed = set(fields)
existing = set(self.fields.keys())
for field_name in existing - allowed:
self.fields.pop(field_name)
filters.py
class CSVFilter(django_filters.Filter):
def filter(self, qs, value):
return super(CSVFilter, self).filter(qs, django_filters.fields.Lookup(value.split(u","), "in"))
class StarsModelFilter(django_filters.FilterSet):
id = CSVFilter(name='id')
class Meta:
model = StarsModel
fields = ['id',]
urls.py
url(r’^/stars/$’, StarsModelList.as_view())
这使我能够构建如下的查询字符串:
/api/stars/?id=1,2,3&fields=type,age,magnetic_field,mass
这很棒我喜欢这个功能,但是还有许多需要应用于此数据的自定义聚合/转换方法。我想做的是像这样有一个agg = param:
/api/stars/?id=1,2,3&fields=type,age,magnetic_field,mass,&agg=complex_method
或只是:
/api/stars/?agg=complex_method
定义complex_method会抓取作业的正确字段。
我不确定从哪里开始以及在哪里添加复杂的方法,所以我真的很感激一些指导。我还应该注意,api仅供私人使用,支持django应用程序,不会向公众开放。
答案 0 :(得分:1)
绝对会很高兴看到你的MyModelList类,但无论如何我的例子都是https://docs.djangoproject.com/en/1.10/ref/class-based-views/base/
from django.http import HttpResponse
from django.views import View
class StarsModelList(generics.ListAPIView):
queryset = StarsModel.objects.all()
serializer_class = StarsModelSerializer
filter_class = StarsModelFilter
def complex_method(request):
# do smth to input parameters if any
return HttpResponse('Hello, World!')
def get(self, request, *args, **kwargs):
if request.GET.get('agg', None) == 'complex_method':
return self.complex_method(request)
return HttpResponse('Hi, World!')