Django-REST

快速入门

基础配置

pip install django
pip install djangorestframework

创建项目

django-admin startproject tutorial

创建App

django-admin startapp quickstart

配置数据库

DATABASES = {
   'default': {
       'ENGINE': 'django.db.backends.mysql',    #数据库引擎
       'NAME': 'django_data',  #数据库名
       'USER': 'xxx',   #账户名
       'PASSWORD': 'xxx', #密码
       'HOST': 'xxxx', #主机
       'PORT': '3306', #端口
  }
}

首次同步数据库

python manage.py migrate

django4略有不兼容

#tutorial/settings.py
import pymysql
pymysql.version_info = (1, 4, 13, "final", 0)
pymysql.install_as_MySQLdb()

创建管理员

python manage.py createsuperuser

序列化程序

from django.contrib.auth.models import User,Group
from rest_framework import serializers


class UserSerializer(serializers.HyperlinkedModelSerializer):
   class Meta:
       model = User
       fields = ['url', 'username', 'email', 'groups']
       
class GroupSerializer(serializers.HyperlinkedModelSerializer):
   class Meta:
       medel = Group
       fields = ['url','name']
       
       

编写视图

from django.contrib.auth.models import User, Group
from rest_framework import viewsets
from rest_framework import permissions
from tutorial.quickstart.serializers import UserSerializer, GroupSerializer


class UserViewSet(viewsets.ModelViewSet):
   """
  API endpoint that allows users to be viewed or edited.
  """
   queryset = User.objects.all().order_by('-date_joined')
   serializer_class = UserSerializer
   permission_classes = [permissions.IsAuthenticated]


class GroupViewSet(viewsets.ModelViewSet):
   """
  API endpoint that allows groups to be viewed or edited.
  """
   queryset = Group.objects.all()
   serializer_class = GroupSerializer
   permission_classes = [permissions.IsAuthenticated]

编写网址

from django.urls import path, include
from rest_framework import routers
from quickstart import views

router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)

urlpatterns = [
   path('', include(router.urls)),
   path('api-auth/',include('rest_framework.urls',namespace='rest_framework'))
]

分页

REST_FRAMEWORK = {
   'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
   'PAGE_SIZE': 10
}

app注册

INSTALLED_APPS = [
   ...
   'quickstart',
   'rest_framework'
]

 

测试接口

准备

http://127.0.0.1:8000/users/

 

 

序列化

序列化(Serialization)是指将Python对象转换为可以在不同应用程序、服务之间传输的格式,例如JSON或XML。

准备

python manage.py startapp snippets

注册app

'snippets',
'rest_framework'

创建模型

from django.db import models
from pygments.lexers import get_all_lexers
from pygments.styles import get_all_styles

LEXERS = [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']

 

这段代码是一个Django模型定义,定义了一个名为Snippet的模型,表示一个代码片段,其中包含了一些元数据和代码内容。模型中定义的字段包括:

  • created: 一个DateTimeField,表示该代码片段的创建时间,使用auto_now_add=True参数可以在模型对象创建时自动设置为当前时间。

  • title: 一个CharField,表示该代码片段的标题,使用max_length=100参数可以限制标题的长度为100个字符,blank=True参数表示该字段可以为空,default=''表示该字段默认值为空字符串。

  • code: 一个TextField,表示该代码片段的内容,使用TextField可以支持更长的文本,如代码。

  • linenos: 一个BooleanField,表示是否显示行号,default=False表示默认情况下不显示行号。

  • language: 一个CharField,表示该代码片段的编程语言,使用choices=LANGUAGE_CHOICES参数可以限制该字段只能从预定义的编程语言选项中选择,default='python'表示默认选择Python编程语言。

  • style: 一个CharField,表示该代码片段的颜色方案,使用choices=STYLE_CHOICES参数可以限制该字段只能从预定义的颜色方案选项中选择,default='friendly'表示默认选择Friendly颜色方案。

在该模型定义中,LEXERSLANGUAGE_CHOICESSTYLE_CHOICES分别定义了Pygments库中所有可用的语言、语言选项和颜色方案选项。LANGUAGE_CHOICESSTYLE_CHOICES用于限制languagestyle字段的选项,以确保用户只能选择支持的选项。ordering=['created']表示在查询该模型时,结果按照创建时间排序。

 

同步数据库

python manage.py makemigrations snippets
python manage.py migrate snippets

 

创建序列化程序类

开始使用 Web API 的第一件事是提供一种将代码段实例序列化和反序列化为表示形式的方法,例如 .我们可以通过声明与 Django 的形式非常相似的序列化程序来做到这一点。在名为的目录中创建一个文件并添加以下内容。

from rest_framework import serializers
from snippets.models import Snippet,LANGUAGE_CHOICES,STYLE_CHOICES

class 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):
       return Snippet.objects.create(**validated_data)

   def update(self, instance, validated_data):
       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

使用模型序列化程序

class SnippetSerializer(serializers.ModelSerializer):
  class Meta:
      model = Snippet
      fields = ['id', 'title', 'code', 'linenos', 'language', 'style']

序列化程序具有的一个很好的属性是,您可以通过打印序列化程序实例的表示形式来检查序列化程序实例中的所有字段。使用 打开 Django shell,然后尝试以下操作:python manage.py shell

from snippets.serializers import SnippetSerializer
serializer = SnippetSerializer()
print(repr(serializer))
# SnippetSerializer():
#   id = IntegerField(label='ID', read_only=True)
#   title = CharField(allow_blank=True, max_length=100, required=False)
#   code = CharField(style={'base_template': 'textarea.html'})
#   linenos = BooleanField(required=False)
#   language = ChoiceField(choices=[('Clipper', 'FoxPro'), ('Cucumber', 'Gherkin'), ('RobotFramework', 'RobotFramework'), ('abap', 'ABAP'), ('ada', 'Ada')...
#   style = ChoiceField(choices=[('autumn', 'autumn'), ('borland', 'borland'), ('bw', 'bw'), ('colorful', 'co

重要的是要记住,类不会做任何特别神奇的事情,它们只是创建序列化程序类的快捷方式:ModelSerializer

  • 一组自动确定的字段。

  • 和方法的简单默认实现。create()``update()

使用序列化程序编写常规的django视图

from django.shortcuts import render

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

#我们 API 的根将是一个支持列出所有现有代码段或创建新代码段的视图。
@csrf_exempt
def snippet_list(request):
   if 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 令牌的客户端 POST 到此视图,因此我们需要将视图标记


@csrf_exempt
def snippet_detail(request,pk):
   try:
       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)
       

将视图写入网址

#snippets/urls.py
from django.urls import path
from snippets import views

urlpatterns = [
   path('snippets/',views.snippet_list),
   path('snippets/<int:pk>/',views.snippet_detail)
]

根网址的设置

from django.urls import path, include

urlpatterns = [
   path('', include('snippets.urls')),
]

测试

http http://127.0.0.1:8000/snippets/
http http://127.0.0.1:8000/snippets/2/

总结

一个简单的业务逻辑

  • 清晰整个结构,需要哪些数据--写models--数据库同步

  • 根据业务需求写序列化器,如果没有特殊需求则使用模板序列化器

  • 视图(views)在drf中实际上就是写接口

  • 然后链接到url中

 

 

 

 

 

 

 

 

 

posted @ 2023-05-06 16:08  qfzwy  阅读(97)  评论(0)    收藏  举报