• django rest_framework入门五-认证和权限


    1.django User实体
    django自带了用户验证模块,django/contrib/auth/models.py定义了用户实体,代码如下:

    class AbstractUser(AbstractBaseUser, PermissionsMixin):
    	username = ''
    	first_name = ''
    	last_name = ''
    	email = ''
    	password = ''
    	...
    

    2.django中获取验证用户

    def get(self, request):
    	user = request.user
    

    3.Snippet实体和User关联
    我们要知道每个Snippet实体是由哪个User创建的
    首先,在Snippet实体中,定义Owner字段,关联User实体对象
    编辑snippets/models.py,代码如下:

    class Snippet(models.Model):
        created = models.DateTimeField(auto_now_add=True)
        title = models.CharField(max_length=100, blank=True, default='')
        code = models.TextField()
        linenos = models.BooleanField(default=False)
        language = models.CharField(choices=LANGUAGE_CHOICES, default='python', max_length=100)
        style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100)
        owner = models.ForeignKey('auth.User', related_name='snippets')
    
        class Meta:
            ordering = ('created',)
    

    重建数据库,在数据库中,owner对应的是owner_id字段,和User的id关联,而在model中owner关联的是User对象

    4.在SnippetSerializer中,添加owner字段
    将owner字段作为SnippetSerializer的一个字段,但只需要读,不需要显式的去写,其实也可以写,只是我们在view中,
    perform_create的时候做了处理,将owner值添加到了SnippetSerializer,所以SnippetSerializer中只需要定义只读就可以了。
    编辑snippets/serializers.py,代码如下:

    class SnippetSerializer(serializers.ModelSerializer):
        owner = serializers.ReadOnlyField(source='owner.username')
        class Meta:
            model = Snippet
            fields = ("id", "created", "title", "code", "linenos", "language", "style", "owner")
    

    source定义了要显示的对象属性

    编辑view视图,将owner值添加到了SnippetSerializer

    class SnippetViewSet(viewsets.ModelViewSet):
        queryset = Snippet.objects.all()
        serializer_class = SnippetSerializer
    
        def perform_create(self, serializer):
            serializer.save(owner=self.request.user)
    

    5.通过http访问接口
    启用rest_framework的登入登出功能
    在urls.py中,新增代码如下:

    urlpatterns += [
        url(r'^api-auth/', include('rest_framework.urls',
                                   namespace='rest_framework')),
    ]
    

    这样,在页面中就可以看到Login,Logout按钮了
    访问地址: http://127.0.0.1:8000/snippets,新增snippet实体,返回结果如下:

    可以看到,显示了owner字段的username属性
    再来看看数据中,显示的结果:

    django会将owner对应为owner_id,显示forergin_key对应对象的id

    6.通过api访问接口

    添加Authorization值username,password

    7.User关联Snippet实体
    如果想找到User下面对应的Snippet列表,该如何编写?
    将snippet放到UserSerializer对应的字段,代码如下:

    class UserSerializer(serializers.ModelSerializer):
        snippets = serializers.PrimaryKeyRelatedField(many=True, queryset=Snippet.objects.all())
    
        class Meta:
            model = User
            fields = ("id", "username", "snippets")
    

    8.设置权限,只有授权用户才能新增snippet
    需要在view视图中设置permission_classes字段,代码如下:

    class SnippetViewSet(viewsets.ModelViewSet):
        queryset = Snippet.objects.all()
        serializer_class = SnippetSerializer
        permission_classes = (permissions.IsAuthenticatedOrReadOnly, )
    
        def perform_create(self, serializer):
            serializer.save(owner=self.request.user)
    

    IsAuthenticatedOrReadOnly表示可以读,或者授权用户才能进行增删改操作

    9.设置权限,只有owner才能进行增删改
    我们需要自定义一个permission类,当当前用户和owner一致时,返回True,否则返回False
    新增文件snippets/permissions.py,代码如下:

    from rest_framework import permissions
    
    
    class IsOwnerOrReadOnly(permissions.BasePermission):
        def has_object_permission(self, request, view, obj):
            if request.method in permissions.SAFE_METHODS:
                return True
            return obj.owner == request.user
    

    修改view视图文件

    class SnippetViewSet(viewsets.ModelViewSet):
        queryset = Snippet.objects.all()
        serializer_class = SnippetSerializer
        permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly, )
    
        def perform_create(self, serializer):
            serializer.save(owner=self.request.user)
    
  • 相关阅读:
    接口测试工具postman(一)下载安装说明
    数据库学习(四)with as (补充 nvl 和 count 函数)
    数据库学习(三) sql语句中添加函数 to_char,round,连接符||
    数据库学习(二) case when then else end 的使用
    数据库学习(一) 一些查询语句
    JMeter学习笔记(九) 参数化4--User Variables
    JMeter学习笔记(九) 参数化3--User Defined Variables
    Python重点(进阶篇)
    Python基础篇练习题
    1
  • 原文地址:https://www.cnblogs.com/shijingjing07/p/9090561.html
Copyright © 2020-2023  润新知