一、反向关系的序列化
官网:https://q1mi.github.io/Django-REST-framework-documentation/api-guide/relations/#reverse-relations
讲解:
1、在models.py
文件中,在模型中设置related_name
参数,如 StudentDetails 和 Courses;
2、在serializers.py
文件,将其字段显示的添加到字段列表中,如:StudentsSerializer
3、在序列化器中,定义 depth
参数
from django.db import models
# Create your models here.
class Students(models.Model):
CHOICES = [
('1', '男'),
('2', '女'),
('3', '未知')
]
name = models.CharField(help_text='学生名称', verbose_name='学生名称', max_length=20)
age = models.IntegerField(help_text='学生年龄', verbose_name='学生年龄', null=False)
sex = models.CharField(help_text='性别', verbose_name='性别', choices=CHOICES, max_length=5)
qq = models.CharField(help_text='qq号', verbose_name='qq号', null=True, blank=True, max_length=10)
phone = models.CharField(help_text='手机号', verbose_name='手机号', null=True, blank=True, max_length=11)
create_time = models.DateTimeField(auto_now_add=True)
# 设置外键,建立关联关系
channel = models.ForeignKey('Channels', on_delete=models.PROTECT, null=True)
class Meta:
db_table = 'tb_students'
verbose_name = '学生表'
verbose_name_plural = verbose_name
db_table_comment = '学生表'
def __str__(self):
return self.name
class Channels(models.Model):
title = models.CharField(help_text='渠道名称', verbose_name='渠道名称', max_length=20)
class Meta:
db_table = 'tb_channels'
verbose_name = '渠道表'
verbose_name_plural = verbose_name
db_table_comment = '渠道表'
def __str__(self):
return self.title
class StudentDetails(models.Model):
"""学生详情表"""
city = models.CharField(help_text='城市', verbose_name='城市', max_length=20, null=True, blank=True)
company = models.CharField(help_text='公司', verbose_name='公司', max_length=20, null=True, blank=True)
station = models.CharField(help_text='部门', verbose_name='部门', max_length=20, null=True, blank=True)
student = models.OneToOneField('Students',
related_name='s1', help_text='学生id', verbose_name='学生id', on_delete=models.CASCADE)
def __str__(self):
return self.student.name
class Meta:
db_table = 'tb_student_detail'
verbose_name = "学生详情表"
verbose_name_plural = verbose_name
db_table_comment = "学生详情表"
class Courses(models.Model):
name = models.CharField(help_text='部门', verbose_name='部门', max_length=20)
students = models.ManyToManyField('Students', through='Entry', related_name='s2')
def __str__(self):
return self.name
class Meta:
db_table = 'tb_courses'
verbose_name = '课程'
verbose_name_plural = verbose_name
class Entry(models.Model):
courses = models.ForeignKey('Courses', on_delete=models.PROTECT)
students = models.ForeignKey('Students', on_delete=models.PROTECT)
c_time = models.DateTimeField(auto_now_add=True)
class StudentsSerializer(ModelSerializer): #
channelss = serializers.CharField(source='channel.title')
# courses = serializers.StringRelatedField(many=True, source='courses_set')
# studentDetailss = NestStudentsSerializer(source='studentDetail')
class Meta:
model = Students
# fields = '__all__'
depth = 3
fields = ['id', 'channelss', 's1', 's2', 'name', 'age']
二、常用命令
# 创建超级管理员账号
python .\manage.py createsuperuser
序列化器的工作流程:
待补充:
自定义权限:
1、视图级权限:has_permission(self, request, view)
2、对象级权限:has_object_permission(self, request, view, obj)
三、明确指定序列化字段
前言:https://q1mi.github.io/Django-REST-framework-documentation/api-guide/serializers_zh/#_22
核心:额外的字段可以对应模型上任何属性
或可调用的方法
如下:
class StudentDetail(models.Model):
STATION_CHOICES = [
('功能测试工程师', '功能测试工程师'),
('自动化测试工程师', '自动化测试工程师'),
('测试开发工程师', '测试开发工程师'),
('测试组长', '测试组长'),
('测试经理', '测试经理')
]
student = models.OneToOneField('Student', verbose_name='学生', help_text='学生', on_delete=models.CASCADE)
city = models.CharField(help_text='城市', verbose_name='城市', null=True, blank=True, max_length=20)
station = models.CharField('岗位', choices=STATION_CHOICES, max_length=10, default='功能测试工程师',
help_text='岗位')
# 新写了一个方法或属性,然后在serializer文件中调用
@property
def student_name(self):
return self.student.name
def __str__(self):
return self.student.name
class Meta:
db_table = 'tb_student_detail'
verbose_name = '学生详情表'
verbose_name_plural = verbose_name
在下面的文件中 fields = ['id', 'student', 'city', 'station', 'student_name']
,
新加了一个student_name
字段,它会自动在模型中查找该属性或者方法,默认为只读
class StudentDetailSerializer(ModelSerializer):
class Meta:
model = StudentDetail
fields = ['id', 'student', 'city', 'station', 'student_name']
extra_kwargs = {
'student': {
'write_only': True
}
}