Efi*_*fie 1 django django-views django-rest-framework
概述-我正在创建一个Django REST API,该API从嵌套的url路由返回数据。到目前为止,我发现最好的方法是手动将url正则表达式添加到urls.py中,然后在我的视图中使用@detail_route来检索已过滤的序列化器数据。
现在,我有一些用户对象和目标对象,它们需要基于身份验证等的不同数据响应。
如何自定义详细路线以执行此操作?例如:
如果用户是管理员,则可以在/ api / v2 / users网址中使用“ post”方法。如果未通过身份验证,则会收到错误的请求400响应。
如果用户是管理员,则可以使用“获取”方法来检索所有用户名,电子邮件和密码,但是如果不是,则只能获取用户名。
urls.py
urlpatterns = [
url(r'^api/v2/users/$',
UserViewSet.as_view({'get': 'users', 'post': 'users', 'put': 'users',
'patch': 'users', 'delete': 'users'}),
name='user_list'),
url(r'^api/v2/user/(?P<uid>\d+)/goals/$',
UserViewSet.as_view({'get': 'user_goals', 'post': 'user_goals', 'put': 'user_goals',
'patch': 'user_goals', 'delete': 'user_goals'}),
name='user_goals_list'),
]
Run Code Online (Sandbox Code Playgroud)
serializers.py
class GoalSerializer(serializers.ModelSerializer):
class Meta:
model = Goal
fields = ('id', 'user_id', 'name', 'amount',
'start_date', 'end_date', )
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('username', 'email', 'id', 'password')
read_only_fields = ('id', )
extra_kwargs = {'password': {'write_only': True}}
Run Code Online (Sandbox Code Playgroud)
views.py
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = serializers.UserSerializer
@detail_route(methods=['get', 'post', 'delete', 'put', 'patch', ])
def users(self, request):
users = User.objects.all()
serializer = serializers.UserSerializer(
users, many=True
)
return Response(serializer.data)
@detail_route(methods=['get', 'post', 'delete', 'put', 'patch', ])
def user_goals(self, request, uid):
goals = Goal.objects.filter(user_id=uid)
serializer = serializers.GoalSerializer(
goals, many=True
)
return Response(serializer.data)
@detail_route(methods=['get', 'post', 'delete', 'put', 'patch', ])
def user_goal_detail(self, request, uid, gid):
goal = Goal.objects.filter(user_id=uid, id=gid)
serializer = serializers.GoalSerializer(
goal, many=True
)
return Response(serializer.data)
Run Code Online (Sandbox Code Playgroud)
就嵌套路由而言,我建议您看一下drf-nested-routers包或类似的包,它会使您的路由工作变得更轻松,请查看SimpleRouter和NestedSimpleRouter类。
如果用户是管理员,则可以在/ api / v2 / users网址中使用“ post”方法。如果未通过身份验证,则会收到错误的请求400响应。
该@detail_route装饰可以接收permission_classes参数,在这里你可以指定执行操作所需的权限声明,就像ViewSet你使用。
然而,你的例子显示了一个ModelViewSet为User模型,这意味着你已经多次行动暴露,以及多个GenericViewSet相关的奖金(get_serializer,get_object,等):
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass
Run Code Online (Sandbox Code Playgroud)
因此,例如,如果您想GET /api/v2/users/通过通过路由器或通过{'get': 'list'}on 进行链接来执行,则可以根据用户urls.py覆盖get_serializer_class方法:
def get_serializer_class(self):
"""
Return the class to use for the serializer.
Defaults to using `self.serializer_class`.
You may want to override this if you need to provide different
serializations depending on the incoming request.
(Eg. admins get full serialization, others get basic serialization)
"""
assert self.serializer_class is not None, (
"'%s' should either include a `serializer_class` attribute, "
"or override the `get_serializer_class()` method."
% self.__class__.__name__
)
return self.serializer_class
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您还可以允许任何人使用,使用的permission_classes参数,否则检查管理员状态:UserViewSetSAFE_METHODS
from rest_framework.permissions import BasePermission, SAFE_METHODS
class IsAdminOrReadOnly(BasePermission):
def has_permission(self, request, view):
if request.method in SAFE_METHODS:
return True
return request.user and request.user.is_staff
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = serializers.UserSerializer
permission_classes = (IsAdminOrReadOnly,)
...
Run Code Online (Sandbox Code Playgroud)
我可能聚会晚了,但是希望这对以后的其他人会有所帮助。
| 归档时间: |
|
| 查看次数: |
423 次 |
| 最近记录: |