一:REST framweork 单表序列化例子
1.新建一个Django项目并创建一个APP
目录结构:
2. sudo pip3 install djangorestframework markdown django-filter # 安装所需模块
3.settings.py
INSTALLED_APPS = [....'rest_framework',]
4.编写测试模型:models.py
from django.db import models# Create your models here.class Classg(models.Model): cname = models.CharField(max_length=20) number = models.IntegerField() teacher = models.ManyToManyField('Teacher', related_name='tracks')class Studnet(models.Model): sname = models.CharField(max_length=20) age = models.IntegerField() sex = models.BooleanField(default=0) classg = models.ForeignKey('Classg', related_name='tracks', on_delete=None) course = models.OneToOneField('Course', on_delete=None)class Course(models.Model): cname = models.CharField(max_length=20)class Teacher(models.Model): tname = models.CharField(max_length=20) # 在本项目的根目录的终端进行同步迁移:
- python3 manage.py migrate
- python3 manage.py makemigrations
- python3 manage.py migrate
5.测试数据插入:在本项目的跟目录创建一个 insert_data.py
import os, django# 外部调用 Django modelsos.environ.setdefault("DJANGO_SETTINGS_MODULE", "proj.settings")django.setup()from celeryapp01.models import *import sysc1 = Classg.objects.create(cname='三年级一班', number=30)c2 = Classg.objects.create(cname='三年级二班', number=60)s1 = Course.objects.create(cname='数学')s2 = Course.objects.create(cname='语文')st1 = Studnet.objects.create(sname='张三', age=28, sex=1, classg=c1, course=s1)st2 = Studnet.objects.create(sname='李四', age=29, sex=0, classg=c2, course=s2)t1 = Teacher.objects.create(tname='比利')t2 = Teacher.objects.create(tname='许Var强')# 多对多正向插入c1.teacher.add(t1)c2.teacher.add(t2)
6.celeryapp01 下创建 rest_serializer.py
from rest_framework import serializersfrom celeryapp01 import modelsclass StudentSerizlizer(serializers.HyperlinkedModelSerializer): class Meta: model = models.Studnet fields = ('sname', 'age', 'sex',) # 这里将 你所想展示出来的字段
7.celeryapp01 下创建 rest_views.py
from rest_framework import viewsetsfrom celeryapp01 import modelsfrom celeryapp01.rest_serializer import StudentSerizlizerclass StudentViewSet(viewsets.ModelViewSet): queryset = models.Studnet.objects.all() serializer_class = StudentSerizlizer
8.在主路由的 urls.py :
from django.contrib import adminfrom django.urls import path,includeurlpatterns = [ path('admin/', admin.site.urls), path(r'celeryapp01/', include('celeryapp01.api_urls')),]
9.app的二级路由 api_urls.py:
from django.urls import path,includefrom celeryapp01 import viewsfrom rest_framework import routersfrom celeryapp01.rest_views import StudentViewSetrouter = routers.DefaultRouter()router.register(r'students', StudentViewSet)urlpatterns = [ path(r'api/', include(router.urls)),] # 逻辑关系
10.访问
------------------------以上是单表序列化--------------------------------
二:REST framweork 多表序列化例子
1.一对一:在 rest_serializer.py 添加如下
# 一对一,一个学生对应一个总分表的行对象class StudentSerizlizer(serializers.HyperlinkedModelSerializer): cname = serializers.CharField(source='course.cname') # 查询与之关联的一对一关系字段 class Meta: model = models.Studnet fields = ('sname', 'age', 'sex', 'cname')class CourseSerizlizer(serializers.HyperlinkedModelSerializer): class Meta: model = models.Course fields = ('cname',)
rest_views.py 添加如下:
class StudentViewSet(viewsets.ModelViewSet): queryset = models.Studnet.objects.all() serializer_class = StudentSerizlizer class CourseViewSet(viewsets.ModelViewSet): queryset = models.Course.objects.all() serializer_class = CourseSerizlizer
api_urls.py 添加如下:
router.register(r'students', StudentViewSet)router.register(r'courses', CourseViewSet)
访问:
2.多对多(多个班级对应多个老师,多个老师对应多个班级):在 rest_serializer.py 添加如下
class ClassgSerizlizer(serializers.HyperlinkedModelSerializer): tracks = serializers.StringRelatedField(many=True) # 一对多 class Meta: model = models.Classg fields = ('cname', 'number', 'tracks')class TeacherSerizlizer(serializers.HyperlinkedModelSerializer): tracks = serializers.PrimaryKeyRelatedField(many=True, read_only=True) # 多对多 class Meta: model = models.Teacher fields = ('tname','tracks')
rest_views.py 添加如下:
class ClassgViewSet(viewsets.ModelViewSet): queryset = models.Classg.objects.all() serializer_class = ClassgSerizlizerclass TeacherViewSet(viewsets.ModelViewSet): queryset = models.Teacher.objects.all() serializer_class = TeacherSerizlizer
api_urls.py:与一对一一样,换成相应的类一下即可
访问:
3.一对多(一个班级对应多个学生)rest_serializer.py添加如下:
class ClassgSerizlizer(serializers.HyperlinkedModelSerializer): tracks = serializers.StringRelatedField(many=True) # 一对多必须要添加这行代码 class Meta: model = models.Classg fields = ('cname', 'number', 'tracks')class StudentSerizlizer(serializers.HyperlinkedModelSerializer): cname = serializers.CharField(source='course.cname') # 查询与之相关联的行对象 class Meta: model = models.Studnet fields = ('sname', 'age', 'sex', 'cname')
rest_views.py :
class ClassgViewSet(viewsets.ModelViewSet): queryset = models.Classg.objects.all() serializer_class = ClassgSerizlizer class TeacherViewSet(viewsets.ModelViewSet): queryset = models.Teacher.objects.all() serializer_class = TeacherSerizlizer
启动:
---------------------------------------------------------------------------
完整代码:
rest_serializer.py
from rest_framework import serializersfrom celeryapp01 import modelsclass ClassgSerizlizer(serializers.HyperlinkedModelSerializer): tracks = serializers.StringRelatedField(many=True) class Meta: model = models.Classg fields = ('cname', 'number', 'tracks')class StudentSerizlizer(serializers.HyperlinkedModelSerializer): cname = serializers.CharField(source='course.cname') class Meta: model = models.Studnet fields = ('sname', 'age', 'sex', 'cname')class CourseSerizlizer(serializers.HyperlinkedModelSerializer): class Meta: model = models.Course fields = ('cname',)class TeacherSerizlizer(serializers.HyperlinkedModelSerializer): tracks = serializers.PrimaryKeyRelatedField(many=True, read_only=True) class Meta: model = models.Teacher fields = ('tname', 'tracks' )
rest_views.py
from rest_framework import viewsetsfrom celeryapp01 import modelsfrom celeryapp01.rest_serializer import StudentSerizlizer, ClassgSerizlizer,CourseSerizlizer,TeacherSerizlizerclass StudentViewSet(viewsets.ModelViewSet): queryset = models.Studnet.objects.all() serializer_class = StudentSerizlizerclass CourseViewSet(viewsets.ModelViewSet): queryset = models.Course.objects.all() serializer_class = CourseSerizlizerclass ClassgViewSet(viewsets.ModelViewSet): queryset = models.Classg.objects.all() serializer_class = ClassgSerizlizerclass TeacherViewSet(viewsets.ModelViewSet): queryset = models.Teacher.objects.all() serializer_class = TeacherSerizlizer
api_urls.py
from django.conf.urls import url,includefrom celeryapp01 import viewsfrom rest_framework import routersfrom celeryapp01.rest_views import StudentViewSet, ClassgViewSet, CourseViewSet,TeacherViewSetrouter = routers.DefaultRouter()router.register(r'students', StudentViewSet)router.register(r'courses', CourseViewSet)router.register(r'classgs', ClassgViewSet)router.register(r'teachers', TeacherViewSet)urlpatterns = [ url(r'api/', include(router.urls)),]
总结:
1.具有一对多、多对多关系的model,也想序列化,必须要在关联字段里添加参数 :related_name='tracks' 如: classg = models.ForeignKey('Classg', related_name='tracks', on_delete=None) 2.
tracks = serializers.StringRelatedField(many=True) #一对多
tracks = serializers.PrimaryKeyRelatedField(many=True, read_only=True) # 多对多
这两个序列化字段很有意思,如:A表和B表关系为一对多,模型的字典字段定义在B表,那么tracks = serializers.StringRelatedField(many=True) 必须写在B序列化的类里 多对多也是如此。