博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
django-rest-framework学习之Authentication & Permissions--2017年4月14日
阅读量:4707 次
发布时间:2019-06-10

本文共 4653 字,大约阅读时间需要 15 分钟。

Authentication & Permissions
 
参考:
 
认证和权限
目前我们的API对于谁可以编辑和删除MyLesson没有任何限制,我们希望添加一些高级的行为使程序具有如下功能:
MyLesson有相应的创建者
只有经过认证的user可以创建MyLesson
只有MyLesson的创建者可以修改和删除MyLesson
没有认证的求情只有可读属性
 
【1】为model增加信息
改变一些MyLesson的model类,首先添加一对Fields,其中一个用来表示MyLesson的创建者,另外一个存储代码的高亮HTML的表现形式
owner = models.ForeignKey('auth.User',related_name='myLesson',on_delete=models.CASCADE)   highlighted = models.TextField()
 
# 对于django.db.models,参考官方文档:https://docs.djangoproject.com/en/1.9/ref/models/fields/#model-field-types
# 文档的右下角可以选择django的版本
# 本程序使用
# DateTimeField(auto_now_add=True),
# CharField(max_length=100, blank=True,default='')
# TextField()
# BooleanField(default=False)
# CharField(choices=LANGUAGE_CHOICES,default='python',max_length=100)
# ForeignKey('auth.User',related_name='myLesson',on_delete=models.CASCADE)
 
我们需要确定的是,当model被保存时,我们植入了highlighted field
使用pygments代码高亮库来完成
from pygments.lexers import get_lexer_by_namefrom pygments.formatters.html import HtmlFormatterfrom pygments import highlightdef save(self, *args, **kwargs):    """     Use the `pygments` library to create a highlighted HTML    representation of the code snippet.    """    lexer = get_lexer_by_name(self.language)    linenos = self.linenos and 'table' or False    options = self.title and {
'title': self.title} or {} formatter = HtmlFormatter(style=self.style, linenos=linenos, full=True, **options) self.highlighted = highlight(self.code, lexer, formatter) super(MyLesson, self).save(*args, **kwargs) # limit the number of instances retained myLesson = MyLesson.objects.all() if len(myLesson) > 100: myLesson[0].delete()

 

然后更新数据库表单,通常我们会迁移数据库,但是在这里,我们直接删掉重新开始
rm -f db.sqlite3
rm -r myLesson/migrations
python manage.py makemigrations myLesson
python manage.py migrate
 
然后创建几个用户做测试
python manage.py createsuperuser
 
【2】为User model增加endpoints
给API添加User的展示页面
在serializer.py中:
from django.contrib.auth.models import User class UserSerializer(serializers.ModelSerializer):    myLesson = serializers.PrimaryKeyRelatedField(many=True,queryset=MyLesson.objects.all())       class Meta:        model = User        fields = ('id','username','myLesson')

 

因为MyLesson和User是是反向关联(reverse relationship,即多对一),所以不会默认添加在ModelSerializer类中,我们需要添加一个明确的field
 
在views.py中我们需要一个只读的view对User做展示,所以我们添加ListAPIView和RetrieveAPIView
from django.contrib.auth.models import Userfrom myLesson.serializers import MyLessonSerializer,UserSerializer class UserList(generics.ListAPIView):    queryset = User.objects.all()    serializer_class = UserSerializer class UserDetail(generics.RetrieveAPIView):    queryset = User.objects.all()    serializer_class = UserSerializer

最后添加这些views到API中,修改urls.py:

url(r'^users/$',views.UserList.as_view()),url(r'^users/(?P
[0-9]+)/$',views.UserDetail.as_view()),

 

【3】连接MyLesson和User
目前,User没有被作为序列化展示的一部分,相反,成了request中的一个属性。
我们在MyLesson views中重写一个perform_create()方法,允许我们修改 实例如何保存,处理隐藏在request中的信息
在MyLessonList类中添加:
def perform_create(self,serializer):    serializer.save(owner=self.request.user)

在create方法中传递owner field,还有我们要创建的数据

 
 【4】升级serializer
在MyLesson中添加owner属性
class MyLessonSerializer(serializers.ModelSerializer):    owner = serializers.ReadOnlyField(source='owner.username')    class Meta:        model = MyLesson        fields = ('id','title','code','linenos','language','style','owner')

ReadOnlyField非常有趣,source参数用来植入一个field,可以用任何Serializer类中的属性,ReadOnlyField可以用CharField(read_only=True)代替

 
【5】为view添加必要的权限
我们希望认证用户可以更新,删除,和创建MyLesson
Rest framework提供了permission类,使我们可以限制谁可以键入一个给定的视图,使用IsAuthenticatedOrReadOnly,来确使认证用户可以读写,其他用户只能只读
在MyLessonList和MyLessonDetail view类中添加如下属性
from rest_framework import permissionspermission_classes = (permissions.IsAuthenticatedOrReadOnly,)

 

【6】为API添加登陆
在项目级别的urls.py中添加以下pattern,允许登入登出
from django.conf.urls import includeurl(r'^api-auth/', include('rest_framework.urls',namespace='rest_framework')),

 

【7】对象级别的权限
只有对象的创建者可以删除和修改:
在MyLesson app中添加permissions.py
from rest_framework import permissionsclass 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        return obj.owner == request.user

 

在views.py中MyLessonDetail中加入
from myLesson.permissions import IsOwnerOrReadOnlypermission_classes = (permissions.IsAuthenticatedOrReadOnly,IsOwnerOrReadOnly,)

 

 

转载于:https://www.cnblogs.com/jingbostar/p/6710215.html

你可能感兴趣的文章
虚拟摇杆跟随鼠标
查看>>
二叉树的建立和遍历算法 - 数据结构和算法47
查看>>
MySQL中select * for update锁表的问题
查看>>
dedecms网站栏目增加缩略图的方法-测试通过
查看>>
抓包(Charles)
查看>>
sphinx安装测试
查看>>
IIS7.5下的asp.net网站不能连接数据库
查看>>
今天我的天空瞬间明亮了
查看>>
elasticsearch.yml基本配置说明
查看>>
主机win7,VMware中debian6采用NET方式上网
查看>>
如何删除github中的仓库?
查看>>
深入学习webpack(三)
查看>>
HBase 高性能加入数据 - 按批多“粮仓”式解决办法
查看>>
Selenium+Java+TestNG环境配置
查看>>
springBoot 打包上线跳过连接数据库
查看>>
表格标签
查看>>
表单验证
查看>>
Android数据存储之文件存储
查看>>
python logging 替代print 输出内容到控制台和重定向到文件
查看>>
半导体知识 原子的共价半径
查看>>