12.权限-修改模型
一、概念
目前为止,我们的api对谁可以编辑或删除代码片段没有任何限制,也就是说没有任何认证和权限相关的设置,通常我们会做一些权限确保
- 每个代码都关联一个创建者
- 只有通过身份验证的用户可以创建片段
- 只有代码片段的创建者可以更新或删除它
- 未经身份验证的请求应具有全部的只读的访问权限
二、为模型添加用户字段
我们对模型类进行一些更改,添加字段用于表示创建代码段段用户
在模型中可以添加.save()方法,它会覆盖父类中的save()方法,添加我们自己的一些逻辑,在保存每一个对象到数据库的时候做的事情
class Snippet(models.Model): title = models.CharField(max_length=100, blank=True, default='') code = models.TextField() created = models.DateTimeField(auto_now_add=True) linenos = models.BooleanField(default=False) # 定义一个外键,指向django.contrib.auth.models.User模型 owner = models.ForeignKey('auth.User',related_name='snippets',on_delete=models.CASCADE) class Mate: ordering = ('created',) # 定义save方法 def save(self,*args,**kwargs): # xxxx代码块 super(Snippet,self).save(*args,**kwargs)
三、创建用户的序列化器
# 导入user模型 from django.contrib.auth.models import User class UserSerializer(serializers.ModelSerializer): # PrimaryKeyRelatedField 将对应的模型序列化成一个列表,存放对应的的主键的数值 # 添加一个snippets序列化字段,值是 对象模型的序列化列表 snippets = serializers.PrimaryKeyRelatedField(many=True,queryset=Snippet.objects.all()) class Meta: model = User fields = ('id', 'username','snippets')
四、用户视图
from django.contrib.auth.models import User class UserList(generics.ListAPIView): queryset = User.objects.all() serializer_class = UserSerializer class UserDetail(generics.RetrieveAPIView): queryset = User.objects.all() serializer_class = UserSerializer
五、urls.py
path('users/',views.UserList.as_view()),
path('users/<int:pk>',views.UserDetail.as_view())
六、完善create
在Snippets模型类里面定义的owner外键是必填项,直接创建数据会报错,所以需要做一些操作
# perform_create 是django给我们提供的一个钩子方法,调用序列化的save()
# 在视图里面重写perform_create方法,为owner提供参数
def perform_create(self, serializer):
# self.request是drf把Django原有request封装
# owner为 Snippet模型类型定义的 关联User外键
# self.request.user,默认后台的会话会往request对象写入一个user,就是服务器当前登录的用户
serializer.save(owner=self.request.user)
# 在urls中分发路由到admin后台url,在页面登录后才可以创建数据
path('api-auth/',include('rest_framework.urls'))
默认 owner字段当前关联的是 当前登录用户的ID
在SnippetSerizlizer里定义字段 可以展示为当前登录的用户名
# source表示这个字段的值来自哪
# ReadOnlyField / 只读
owner = serializers.ReadOnlyField(source='owner.username')
风月都好看,人间也浪漫.