目前我们的API没有限制谁可以编辑和删除代码片段。我们想要一些更高级的行为来确保:

  • 代码片段与创建者关联
  • 只有注册了的用户才可以创建代码片段
  • 只有创建者才能更新或者删除代码片段
  • 未经身份认证的请求只能浏览代码片段

在我们的模型中添加一些信息

我们将对Snippet模型进行一些修改。首先,添加一些字段。第一个字段被用来表示该片段是由哪个用户创建的。另一个被用来存储高亮显示的片段的HTML代码。

models.py中的Snippet模型中添加以下两个字段。

1
2
owner = models.ForeignKey('auth.User', related_name='snippets', on_delete=models.CASCADE)
highlighted = models.TextField()

我们得确保当模型存储时,用pygments代码高亮库去填充高亮字段。

所有还有导入一些东西:

1
2
3
from pygments.lexers import get_lexer_by_name
from pygments.formatters.html import HtmlFormatter
from pygments import highlight

然后在模型类中添加.save()方法:

1
2
3
4
5
6
7
8
9
10
11
12
def 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(Snippet, self).save(*args, **kwargs)

更新一些数据库。通常我们都是利用数据库迁移来完成这一操作,但是出于本教程的目的,我们直接删除数据库再创建吧。

1
2
3
4
rm -f db.sqlite3
rm -r snippets/migrations
python manage.py makemigrations snippets
python manage.py migrate

你可以需要创建一些不同的用户来测试我们的API。创建用户最快的方法就是使用createsuperuser命令。

1
python manage.py createsuperuser

给用户模型添加端点

现在我们有了一些可以用的用户,我们最好给API添加用户的模型表示。创建一个序列器很简单。在serializers.py添加:

1
2
3
4
5
6
7
8
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')

因为snippets与用户模型是一个多对一的关系,使用ModelSerializer类时多的一方默认不生成该关系,所以我们需要为此添加一个字段。

修改views.py。我们想要用户模型表示的视图只能被浏览,所以我们使用通用类视图的ListAPIViewRetrieveAPIView

1
2
3
4
5
6
7
8
9
10
11
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

导入UserSerializer

1
from snippets.serializers import UserSerializer

关联片段和用户

现在,如果我们创建一个代码片段,还不能将创建者和片段关联起来。用户信息不是作为序列化的模型表示的一部分发送,而是作为传入请求的属性。

我们的处理方法是通过重写snippet视图的.perform_create()方法,该方法允许我们修改实例保存时的操作,和处理任何隐含在传入的请求或URL中的信息。

SnippetList视图类中添加下面的方法:

1
2
def perform_create(self, serializer):
serializer.save(owner=self.request.user)

现在通过请求的合法数据,向序列化器中的.create()方法传递额外的owner字段。

给视图添加权限

给Browsable API 添加登陆功能

对象级的权限

用API验证

总结

留言

⬆︎TOP