您现在的位置是:主页 > news > 江苏省交通运输厅门户网站建设管理/数据分析培训班
江苏省交通运输厅门户网站建设管理/数据分析培训班
admin2025/4/29 14:44:42【news】
简介江苏省交通运输厅门户网站建设管理,数据分析培训班,公司如何建设网站,南宁营销型网站制作本人普通一本,正值大三,为了能有好的就业,痛定思痛戒掉游戏!鞭策自己至少一周一篇博客学习目标:学校课内基础打扎实,课外学会语言框架,同时提升英语阅读水平学习路线(自拟)ÿ…

本人普通一本,正值大三,为了能有好的就业,痛定思痛戒掉游戏!鞭策自己至少一周一篇博客
- 学习目标:学校课内基础打扎实,课外学会语言框架,同时提升英语阅读水平
- 学习路线(自拟):
vue
->djangorestframework
->goland
- 毕业前想:用前后端分离建成自己的小站,做一款网络游戏(爱好而已)
关于本篇djangorestframwork
内容皆会上传到我的github上:https://github.com/BadbadLoli/django-rest-framework-study
本篇参照官网教程:https://www.django-rest-framework.org/tutorial/quickstart/
学习为主,如有纰漏请大神指正
介绍
本教程将介绍如何创建一个简单的突出显示代码块的Web API
。在此过程中,它将介绍构成REST框架的各种组件,并让您全面了解所有内容是如何组合在一起的。
项目准备
创建一个新项目tutoria
l,并创建一个新的app snippets
django-admin startproject tutorial
...
python manage.py startapp snippets
然后我们需要告诉django
我们要使用snippets
和restframework
./tutorial/settings.py
INSTALLED_APPS = [...'rest_framework','snippets.apps.SnippetsConfig',
]
创建model
现在,我们创建一个简单的Snippet
模型,用来存储代码块的相关信息
./snippets/models.py
from django.db import models
from pygments.lexers import get_all_lexers
from pygments.styles import get_all_stylesLEXERS = [item for item in get_all_lexers() if item[1]]
LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
STYLE_CHOICES = sorted([(item, item) for item in get_all_styles()])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)class Meta:ordering = ['created']
pygments
是一个优化markdown,对其中的代码块进行高亮的库,不需要做深入了解
模型创建完之后要进行数据迁移
python manage.py makemigrations
...
python manage.py migrate
创建一个Serializer
现在,我们需要在Web API
上把snippet
实例序列化和反序列化为json格式,我们可以通过声明与django
中的表单非常相似的序列化器来实现这一点
./snippets/serializers.py
from rest_framework import serializers
from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICESclass SnippetSerializer(serializers.Serializer):id = serializers.IntegerField(read_only=True)title = serializers.CharField(required=False, allow_blank=True, max_length=100)code = serializers.CharField(style={'base_template': 'textarea.html'})linenos = serializers.BooleanField(required=False)language = serializers.ChoiceField(choices=LANGUAGE_CHOICES, default='python')style = serializers.ChoiceField(choices=STYLE_CHOICES, default='friendly')def create(self, validated_data):# 创建返回一个新的Snippet实例,并附上验证好的数据return Snippet.objects.create(**validated_data)def update(self, instance, validated_data):# 更新返回一个存在的Snippet实例,并附上验证好的数据instance.title = validated_data.get('title', instance.title)instance.code = validated_data.get('code', instance.code)instance.linenos = validated_data.get('linenos', instance.linenos)instance.language = validated_data.get('language', instance.language)instance.style = validated_data.get('style', instance.style)instance.save()return instance
serializer的第一部分是定义需要序列化/反序列化的字段,方法create()和update()则定义了在调用save()方法时如何创建或修改实例
serializer与Django表单类非常相似,并且在各个字段上包含类似的验证标志,比如required、max_length和default
当然,我们也可以用ModelSerializer
类来节省时间,跟django中的表单类ModelForm
类一样
./snippets/serializers.py
class SnippetSerializer(serializers.ModelSerializer):class Meta:model = Snippetfields = ['id', 'title', 'code', 'linenos', 'language', 'style']
要记住,ModelSerializer
类只是创建serializer
的快捷方式,并没有什么神奇的功能,像create()
和update()
方法只是默认实现
使用python manage.py shell
打开django shell
然后尝试以下操作:
- 我们要创建一些实例来使用
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParsersnippet = Snippet(code='foo = "bar"n')
snippet.save()snippet = Snippet(code='print("hello, world")n')
snippet.save()
- 我们现在可以来看看序列化其中一个实例
serializer = SnippetSerializer(snippet)
serializer.data
# {'id': 2, 'title': '', 'code': 'print("hello, world")n', 'linenos': False, 'language': 'python', 'style': 'friendly'}
- 我们还可以序列化
queryset
而不是模型实例。为此,我们只需向序列化器参数添加一个many=True
标志。
serializer = SnippetSerializer(Snippet.objects.all(), many=True)
serializer.data
# [OrderedDict([('id', 1), ('title', ''), ('code', 'foo = "bar"n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 2), ('title', ''), ('code', 'print("hello, world")n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 3), ('title', ''), ('code', 'print("hello, world")'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])]
编写视图View
让我们看看如何使用serializer来编写一些API视图,目前,我们编写的视图为普通的django视图
./snippet/views.py
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.parsers import JSONParser
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer@csrf_exempt
def snippet_list(request):# 展示(GET)所有snippet,或者创建(POST)一个新的snippetif request.method == 'GET':snippets = Snippet.objects.all()serializer = SnippetSerializer(snippets, many=True)return JsonResponse(serializer.data, safe=False)elif request.method == 'POST':data = JSONParser().parse(request)serializer = SnippetSerializer(data=data)if serializer.is_valid():serializer.save()return JsonResponse(serializer.data, status=201)return JsonResponse(serializer.errors, status=400)@csrf_exempt
def snippet_detail(request, pk):# 检索,更新或删除一个snippettry:snippet = Snippet.objects.get(pk=pk)except Snippet.DoesNotExist:return HttpResponse(status=404)if request.method == 'GET':serializer = SnippetSerializer(snippet)return JsonResponse(serializer.data)elif request.method == 'PUT':data = JSONParser().parse(request)serializer = SnippetSerializer(snippet, data=data)if serializer.is_valid():serializer.save()return JsonResponse(serializer.data)return JsonResponse(serializer.errors, status=400)elif request.method == 'DELETE':snippet.delete()return HttpResponse(status=204)
注意,由于我们希望能够从没有CSRF
令牌的客户端向上面的视图发送POST
请求,所以我们要给视图函数加上@csrf_exempt
的装饰器,其实drf视图实际上有比这更合理的行为,但现在为了我们的教学目的,就先这样做吧
最后,我们需要将这些视图连接起来
./snippet/urls.py
from django.urls import path
from snippets import viewsurlpatterns = [path('snippets/', views.snippet_list),path('snippets/<int:pk>/', views.snippet_detail),
]
我们还要连接根url
./tutorial/urls.py
from django.urls import path, includeurlpatterns = [path('', include('snippets.urls')),
]
值得注意的是,有几个边缘情况我们目前没有正确处理。如果我们发送格式不正确的json,或者发送的请求视图无法处理,那么我们将得到一个500的“服务器错误”响应。不过,现在这样就可以了。
测试一下我们的web API
python manage.py runserver
我用的postman进行测试
到目前为止,我们做得还不错,我们有一个序列化API,感觉非常类似于Django的表单API,以及一些常规的Django视图。 目前,我们的API视图除了提供json响应之外,没有做任何特别的事情,我们仍然希望清理一些错误处理的边缘情况,但它是一个功能良好的Web API。
我们将在本教程的第2部分中看到如何开始改进。