Django Rest framework使用问题及解决方法



更新记录

2016-01-29 初稿

问题1

ViewSet没有写serializer_class属性,而是重写了get_serializer_class()方法,出现

1
Cannot use OrderingFilter on a view which does not have either a 'serializer_class' or 'ordering_fields' attribute.

原因:因为启用了rest_framework.filters.OrderingFilter而没有设置ordering_fields
解决方法:ViewSet里加ordering_fields属性,可是禁用rest_framework.filters.OrderingFilter

问题2

ViewSet没有写queryset属性,而是重写了get_queryset()方法,出现

1
'base_name' argument not specified, and could not automatically determine the name from the viewset, as it does not have a '.queryset' attribute.

解决方法:需要在urls.py里给ViewSet注册Router时添加base_namebase_namerouterViewSet注册url时自动添加的name前缀,如果未设置则从ViewSetqueryset里取,使用ViewSet自动生成的url name为<base_name>-list <base_name>-detail 等)
urls.py

1
router.register(r'users', UserViewSet, base_name='user')

问题3

给url设置了namespace
urls.py

1
url(r'^api/', include(router.urls, namespace='api')),

访问部分接口出现

1
Could not resolve URL for hyperlinked relationship using view name "user-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.

解决方法1:给所有的serializer里包含的外键字段手动设置view_name值(注意,继承HyperlinkedModelSerializer,会隐式添加一个HyperlinkedRelatedField字段url,而所有的外键都会变成HyperlinkedRelatedField字段,所以需要对两种类型字段手动设置view_name值)
serializers.py

1
2
3
4
5
6
7
8
class ContactSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Contact
fields = '__all__'
extra_kwargs = {
'url': {'view_name': 'api:contact-detail'},
'user':{'view_name':'api:user-detail'}
}

解决方法2:启动drf基于NameSpace的版本控制
settings.py

1
2
3
4
5
REST_FRAMEWORK = {
……
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.NamespaceVersioning',
……
}

0%