目前,咱们的API对谁能够编辑或删除代码段没有任何限制。咱们想要一些更先进的行为,以确保:(这段话抄自官网)python
使用官方例子在表中添加用户字段,该字段用来判断是否与登陆用户有关系。django
owner = models.ForeignKey('auth.User', related_name='snippets', on_delete=models.CASCADE) highlighted = models.TextField()
这里的owner用户关联的为django admin的认证用户,该字段用与匹配登陆用户是否有权限修改该数据(后面涉及到)。后端
为 auth.User 表添加到api中,首先须要添加序列化。因为snippets(这里的smippets为外键的related_name,默认为"表名_set")在用户模型上是反向关系,因此在使用ModelSerializer 类时它不会被默认包含,须要添加一个显示的字段。api
# 用户序列化函数 serializers.py from django.contrib.auth.models import User class UserSerializer(serializers.ModelSerializer): snippets = serializers.PrimaryKeyRelatedField(many=True, queryset=Snippet.objects.all()) class Meta: model = User fields = ('id', 'username', 'snippets') # 用户视图函数 views.py from django.contrib.auth.models import User from snippets.serializers import UserSerializer class UserList(generics.ListAPIView): queryset = User.objects.all() serializer_class = UserSerializer class UserDetail(generics.RetrieveAPIView): queryset = User.objects.all() serializer_class = UserSerializer # 配置URL conf url(r'^users/$', views.UserList.as_view()), url(r'^users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),
关联用户经过重写SnippetList 视图类的 perform_create(),该方法修改实例保存的管理方式,并处理传入请求或request中的任何信息。app
在SnippetList
视图类上,添加如下方法:(我的理解:使保存的数据用户字段为登陆用户的信息)框架
def perform_create(self, serializer): serializer.save(owner=self.request.user)
snippets 和 user关联后,在snippets中owner的信息默认为id信息,更新序列化类(serializer)是owner显示为用户名信息。ide
# 更新 SmippetSerializer 添加以下: owner = serializers.ReadOnlyField(source='owner.username') # 并确保 fields 中有owner字段。
咱们添加的是无类型的 ReadOnlyField 类,与其余类型的字段(CharField,BooleanField等)相比ReadOnlyField 老是只读的。若是设置为ReadOnlyField 该字段则不用用于更新(可是参数仍是会传递到后端。),咱们也可使用CharField(read_only=Ture)来指定字段类型而且设置为只读字段。函数
既然Snippet和user相关联,咱们但愿只有通过身份验证的用户才能建立,更新和删除代码片断。
url
REST框架包含许多权限类,咱们可使用这些权限类来限制能够访问给定视图的人员。在这种状况下,咱们正在寻找的是IsAuthenticatedOrReadOnly
确保通过身份验证的请求得到读写访问权限,未经身份验证的请求得到只读访问权限。spa
首先在视图模块中添加如下导入:
from rest_framework import permissions
接着,下面的属性添加到都在SnippetList
和SnippetDetail
视图类。
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
在适当的urls.py文件中天剑URLconf在添加可浏览API的登陆视图。
from django.conf.urls import include # 按需添加以下urlconf,r'^api-auth/'模式的部分实际上能够是您想要使用的任何URL。 urlpatterns += [ url(r'^api-auth/', include('rest_framework.urls')), ]
咱们但愿全部人均可以看到全部代码片断,但也要确保只有建立代码段的用户才能更新或删除它。为此,咱们须要建立一个自定义权限。
在app中建立一个新文件,permissions.py
from rest_framework import permissions class IsOwnerOrReadOnly(permissions.BasePermission): """ Custom permission to only allow owners of an object to edit it. """ def has_object_permission(self, request, view, obj): # Read permissions are allowed to any request, # so we'll always allow GET, HEAD or OPTIONS requests. # 当用户请求的为查询操做使,对用户没有限制 if request.method in permissions.SAFE_METHODS: return True # Write permissions are only allowed to the owner of the snippet. # 不然判断用户是否与操做数据的用户相同,返回Ture or False return obj.owner == request.user
添加完以后在SnippetDetail类视图中添加 permission_classes属性来将该自定义权限加到代码中:
记得导入 IsOwnerOrReadOnly (from snippets.permissions import IsOwnerOrReadOnly
)
permission_classes = (permissions.IsAuthenticatedOrReadOnly,IsOwnerOrReadOnly,)