zoukankan      html  css  js  c++  java
  • 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)
    
  • 相关阅读:
    PTA —— 基础编程题目集 —— 函数题 —— 61 简单输出整数 (10 分)
    PTA —— 基础编程题目集 —— 函数题 —— 61 简单输出整数 (10 分)
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    迷宫问题 POJ 3984
    UVA 820 Internet Bandwidth (因特网带宽)(最大流)
    UVA 1001 Say Cheese(奶酪里的老鼠)(flod)
    UVA 11105 Semiprime Hnumbers(H半素数)
    UVA 557 Burger(汉堡)(dp+概率)
  • 原文地址:https://www.cnblogs.com/shijingjing07/p/9090561.html
Copyright © 2011-2022 走看看