ModelSerializer

序列化准备:

  • 配置 settings.py

# 注册rest_framework框架
INSTALLED_APPS = [
...
'rest_framework'
]
# 配置mysql数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db10',
'USER': 'root',
'PASSWORD':'root',
}
}

"""
任何__init__.py文件中
import pymysql
pymysql.install_as_MySQLdb()
"""

# 国际化
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False

# 配置静态文件
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
  • 路由

# 主路由:
from django.conf.urls import url, include
from django.contrib import admin
from django.views.static import serve
from django.conf import settings
urlpatterns = [
url(r'^admin/', admin.site.urls),
# 路由分发
url(r'^api/', include('app01.urls')),
# 暴露media文件夹
url(r'^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT})
]
# 子路由:
from django.conf.urls import url
from . import views

urlpatterns = [
...
]
  • 模型层: models.py

# 多表设计
Book表:name、price、img、authors、publish、is_delete、create_time

Publish表:name、address、is_delete、create_time Author表:name、age、is_delete、create_time

AuthorDetail表:mobile, author、is_delete、create_time

知识补充:

  • 基表

# 上述的表中都含有 is_delete、create_time 字段,我们可以创建一个基表类含有这两个字段,其他的表来继承这个基表类即可(类似抽象类)

class BaseModel(models.Model):
is_delete = models.BooleanField(default=False) # 该字段默认是 0
create_time = models.DateTimeField(auto_now_add=True)

# 作为基表的model类不能在数据库中形成对应的表,所以一定需要设置 abstract = True
class Meta:
abstract = True
  • 断关联多表关系(***)

1、外键位置:
一对多 - 外键放多的一方
一对一 - 从逻辑正反向考虑,如作者表与作者详情表,作者删除级联删除详情,详情删除作者依旧存在,所以建议外键在详情表中
多对多 - 外键在关系表中
2、ORM正向方向连表查找:
正向:通过外键字段 eg: author_detial_obj.author
反向:通过related_name的值 eg:author_obj.detail
注:依赖代码见下方
3、连表操作关系:
1)作者删除,作者详情级联 - on_delete=models.CASCADE # 被关联表中的数据删除,主关联表中的对应数据也删除
2)作者删除,作者详情置空 - null=True, on_delete=models.SET_NULL # 被关联表中的数据删除,主关联表中的对应的字段为空(null)
3)作者删除,作者详情重置 - default=0, on_delete=models.SET_DEFAULT # 被关联表中的数据删除,主关联表中的对应数据字段可以通过事先定义好的default=0改为0
4)作者删除,作者详情不动 - on_delete=models.DO_NOTHING # 被关联表中的数据删除,主关联表中的数据不做任何处理
注:拿作者与作者详情表举例
4、外键关联字段的参数 - 如何实现 断关联、目前表间操作关系、方向查询字段
- 图书表中:
# 关联出版社外键字段
publish = models.ForeignKey(
to='Publish',
db_constraint=False, # book表与publish表在库中段关联,但在逻辑上还是有关系
related_name='books', # 反向跨表时按related_name定义的名字即可
on_delete=models.DO_NOTHING, # 断级联,当出版社删除时,对应的图书不做任何处理
)
# 关联作者外键字段
authors = models.ManyToManyField(
to='Author',
db_constraint=False,
related_name='books',
)
- 作者详情表中
author = models.OneToOneField(
to='Author',
db_constraint=False,
related_name='detail',
on_delete=models.CASCADE, # 级联
)
注意:
1.ManyToManyField不能设置on_delete,OneToOneField、ForeignKey必须设置on_delete(django1.x系统默认级联,但是django2.x必须手动明确)
2.OneToOneField 本质是继承了 ForeignKey
from django.db import models

# 基表
class BaseModel(models.Model):
is_delete = models.BooleanField(default=False) # 该字段默认是 0
create_time = models.DateTimeField(auto_now_add=True)

# 作为基表的model类不能在数据库中形参对应的表,所以需要设置 abstract = True
class Meta:
abstract = True

# 图书表
class Book(BaseModel): # 继承基表,就会继承基表中的字段
name = models.CharField(max_length=64)
price = models.DecimalField(max_digits=5, decimal_places=2)
img = models.ImageField(upload_to='img', default='img/default.jpg')
# 关联出版社外键字段
publish = models.ForeignKey(
to='Publish',
db_constraint=False, # book表与publish表在库中段关联,但在逻辑上还是有关系
related_name='books', # 反向跨表时按related_name定义的名字即可
on_delete=models.DO_NOTHING, # 断级联,当出版社删除时,对应的图书不错任何处理
)
# 关联作者外键字段
authors = models.ManyToManyField(
to='Author',
db_constraint=False,
related_name='books',
) # ModelSerializer序列化 自定义序列化字段方式1
@property
def publish_name(self):
return self.publish.name # 利用跨表查询返回publish的name
@property
def author_list(self):
return self.authors.values('name', 'detail__mobile'
)

class Meta:
db_table = 'book'
verbose_name = '书籍'
verbose_name_plural = verbose_name

def __str__(self):
return self.name

class Publish(BaseModel):
name = models.CharField(max_length=64)
address = models.CharField(max_length=64)

class Meta:
db_table = 'publish'
verbose_name = '出版社'
verbose_name_plural = verbose_name

def __str__(self):
return self.name

class Author(BaseModel):
name = models.CharField(max_length=64)
age = models.IntegerField()

class Meta:
db_table = 'author'
verbose_name = '作者'
verbose_name_plural = verbose_name

def __str__(self):
return self.name

class AuthorDetail(BaseModel):
mobile = models.CharField(max_length=11)
author = models.OneToOneField(
to='Author',
db_constraint=False,
related_name='detail',
on_delete=models.CASCADE, # 级联
)

class Meta:
db_table = 'author_detail'
verbose_name = '作者详情'
verbose_name_plural = verbose_name

def __str__(self):
return '%s的详情' %self.author.name

ModelSerializer 序列化 使用:

  • 应用下创建 serializers.py

from rest_framework.serializers import ModelSerializer, SerializerMethodField
from . import models
from rest_framework.exceptions import ValidationError

# 创建Book模类的序列化类
class BookModelSerializer(ModelSerializer):
class Meta:
# 自定义序列化字段方法2: 该方式设置的序列化字段,必须在fields中声明
# publish_address = SerializerMethodField()
# def get_publish_addr(self, obj): obj为当前Book对象
# return obj.publish.address

# 1.序列化关联的model类
model = models.Book
# 2.参与序列化的字段(插拔式),可选择字段展示(model类中有的字段都可以展示,也可以在model类中自定义字段来展示)
fields = ('name', 'price','publish_name') # 这里直接写外键字段,到前端展示的是对应model类一条记录的外键pk值

# 了解
# fields = '__all__' # 展示所有model类字段,除model中自定义的方法字段
# exclude = ('id', 'is_delete', 'create_time') # 不展示的字段
# depth = 1 # 自动连表深度
  • 视图层

from rest_framework.views import APIView
from rest_framework.response import Response

from . import models, serializers

class Book(APIView):
def get(self, request, *args, **kwargs):
pk = kwargs.get('pk')
if pk:
try:
# 根据pk查询对应的书籍,注意要指定is_delete=False,因为被删除的数据不能给用户查看
book_obj = models.Book.objects.get(pk=pk, is_delete=False)
# model对象不能直接返回给前端,需要序列化,拿到serializers对象字典
book_data = serializers.BookModelSerializer(book_obj).data
except:
return Response({
'status': 1,
'msg': '书籍不存在'
})
else:
# 查所有
book_query = models.Book.objects.filter(is_delete=False).all()
# 序列化 注意: book_query是列表,序列化是要指定many=True
book_data = serializers.BookModelSerializer(book_query, many=True).data
return Response({
'status': 0,
'msg': 'ok',
'results': book_data
})
  • 路由层

urlpatterns = [
url(r'^books/$', views.Book.as_view()),
url(r'^books/(?P<pk>.*)/$', views.Book.as_view()),
]

ModelSerializer 反序列化 使用:

  • serializers.py文件中:

# 创建Book模型类的反序列化类
class BookModelDeserializer(ModelSerializer):
class Meta:
# 序列化关联的model类
model = models.Book
# 1.fields内的变量名(字段)要对应关联的model类,
# 2.fields内的字段是前端发来的,字段有默认值的可以不参与反序列化
fields = ('name', 'price', 'publish', 'authors')
# extra_kwargs 用来完成反序列化字段的 系统校验规则
extra_kwargs = {
'name': {
'required': True,
'min_length':1,
'error_messages': {'required':'必填项', 'min_length': '太短',}
}
}
# 局部钩子
def validate_name(self, value):
# 书名不能包含 K 字符
if 'k' in value.lower():
raise ValidationError('函非法字符')
return value
# 全局钩子
def validate(self, attrs): # attrs 是个字典
print(attrs)
# OrderedDict([('name', '三国'), ('price', Decimal('2.33')), ('publish', <Publish: 首都出版社>), ('authors', [<Author: hanmm>])])
publish = attrs.get('publish')
print(publish, type(publish))
# 首都出版社 <class 'app01.models.Publish'>
name = attrs.get('name')
print(name, type(name))
# 三国 <class 'str'> # 同一出版社的书不能重复创建
if models.Book.objects.filter(name=name, publish=publish):
raise ValidationError({'book': '该书已存在'})
return attrs

# ModelSerializer类已经帮我们实现了 create 与 update 方法
  • 视图层

class Book(APIView):
def post(self, request, *args, **kwargs):
# 拿到数据包中的数据字典
request_data = request.data
# 将数据包字典反序列化并校验,拿到序列化后的对象
book_ser = serializers.BookModelDeserializer(data=request_data)
# 当校验失败,马上终止当前视图方法,抛异常返回给前台
book_ser.is_valid(raise_exception=True) # 指定参数raise_exception=True, 当 book_ser.is_valid为False时自动向前端抛出错误
book_obj = book_ser.save()
return Response({
'status': 0,
'msg': 'ok',
'results': serializers.BookModelSerializer(book_obj).data
})

注意:

ser_obj = CarModelSerializer(数据)  # 产生序列化类对象(可能参与序列化,也可能参与反序列化)
ser_obj.data # 序列化的数据
ser_obj.is_valid() # 启动序列化校验规则(系统内容=>局部钩子=>全局钩子)源码中run_validation调用一系列的校验规则
ser_obj.save() # 序列化校验后的数据操作(保存,修改)
  • 路由层

urlpatterns = [
url(r'^books/$', views.Book.as_view()),
url(r'^books/(?P<pk>.*)/$', views.Book.as_view()),
]

ModelSerializer 序列化反序列化整合(*****)

1) fields中设置所有序列化与反序列化字段(插拔式)
2) extra_kwargs划分只序列化或只反序列化字段
write_only:只反序列化 (要写入数据库的字段)
read_only:只序列化 (要展示给前端的字段)
自定义字段默认只序列化(read_only)
3) 设置反序列化所需的 系统、局部钩子、全局钩子 等校验规则
  • serializers.py文件中:

class V2BookModelSerializer(ModelSerializer):
class Meta:
model = models.Book
# 设置所有字段
fields = ('name', 'price', 'img', 'author_list', 'publish_name', 'publish', 'authors')
# extra_kwargs划分只序列化或只反序列化字段
extra_kwargs = {
'name': {
'required': True,
'min_length': 1,
'error_messages': {'required': '必填项', 'min_length': '太短', },
},
'publish': { 'write_only': True }, # 外键字段序列化到前端就是一个数字,所有没不要参与序列化,但有必要参与反序列化
'authors': {'write_only': True },
'img': {'read_only': True},
'author_list': {'read_only': True},
'publish_name': { 'read_only': True}
}

# 局部钩子
def validate_name(self, value):
# 书名不能包含 K 字符
if 'k' in value.lower():
raise ValidationError('函非法字符')
return value

# 全局钩子
def validate(self, attrs): # attrs 是个字典
print(attrs)
# OrderedDict([('name', '三国'), ('price', Decimal('2.33')), ('publish', <Publish: 首都出版社>), ('authors', [<Author: hanmm>])])
publish = attrs.get('publish')
print(publish, type(publish))
# 首都出版社 <class 'app01.models.Publish'>
name = attrs.get('name')
print(name, type(name))
# 三国 <class 'str'>
if models.Book.objects.filter(name=name, publish=publish):
raise ValidationError({'book': '该书已存在'})
return attrs
  • 视图层

查 - 单查 | 群查

增 - 单增 | 群增

删 - 单删 | 群删

class V2Book(APIView):
# 单查 有pk(有指定的查)
# 群查 无pk
def get(self, request, *args, **kwargs):
pk = kwargs.get('pk')
if pk:
try:
book_obj = models.Book.objects.get(pk=pk, is_delete=False)
book_data = serializers.V2BookModelSerializer(book_obj).data
except:
return Response({
'status': 1,
'msg': '书籍不存在'
})
else:
book_query = models.Book.objects.filter(is_delete=False).all()
book_data = serializers.V2BookModelSerializer(book_query, many=True).data
return Response({
'status': 0,
'msg': 'ok',
'results': book_data
})

# 单增 : 传输的数据包是一个与model类对应的字典, 需要逻辑判断
# 群层 : 传输的数据包是一个装了多个与model类对应的列表, 需要逻辑判断
def post(self, request, *args, **kwargs):
request_data = request.data
# 单增与群增的代码一样,区别在与反序列化时是否指定many=True
if isinstance(request_data, dict): # 判断request_data是否是dict的对象
# 是单增 many=False
many = False
elif isinstance(request_data, list): # 判断request_data是否是dict的对象
# 是群增 many=True
many = True
else:
# 都没通过数据有误
return Response({
'status': 1,
'msg': '数据有误',
})
# 反序列化
book_ser = serializers.V2BookModelSerializer(data=request_data, many=many)
# 校验字段是否都符合
book_ser.is_valid(raise_exception=True)
book_obj_list = book_ser.save()
print(book_obj_list, type(book_obj_list)) # [<Book: 东游>, <Book: 水浒>] <class 'list'>
return Response({
'status': 0,
'msg': 'ok',
'results':serializers.V2BookModelSerializer(book_obj_list, many=many).data
})

# 单删 有pk 指定一个pk
# 群删 有pks 指定多个pk {"pks": [1, 2, 3]}
def delete(self, request, *args, **kwargs):
pk = kwargs.get('pk')
if pk:
pks = [pk]
else:
pks =request.data.get('pks')
# 返回修改几条记录的数量
num = models.Book.objects.filter(pk__in=pks, is_delete=False).update(is_delete=True)
if num:
return Response({
'status': 0,
'msg': '删除成功',
})
return Response({
'status': 1,
'msg': '删除失败',
})
  • 路由层

from django.conf.urls import url
from . import views

urlpatterns = [
url('^v2/books/$', views.V2Book.as_view()),
url('^v2/books/(?P<pk>.*)/$', views.V2Book.as_view()),
]

改的操作:

单改 - 单整体改 | 单局部改

群改 - 群整体改 | 群局部改

1) 单整体改,说明前台要提供修改的数据,那么数据就需要校验,校验的数据应该在实例化“序列化类对象”时,赋值给data
2)修改,就必须明确被修改的模型类对象,并在实例化“序列化类对象”时,赋值给instance
3)整体修改,所有校验规则有required=True的字段,都必须提供,因为在实例化“序列化类对象”时,参数partial默认为False
1.单整体修改,一般用put请求:# 如果partial值设置为True,就是可以局部改
book_ser = serializers.V2BookModelSerializer(
instance=book_obj, # instance是要被修改的对象,有这个参数就是修改,没有就是增加
data=request_data, # 参与反序列化校验的数据信息
partial=False, # partial默认就是False,意思是每个必须字段都要有,也就是整体改,反之是局部改
)
2.单局部修改,一般用patch请求:
V2BookModelSerializer(
instance=要被更新的对象,
data=用来更新的数据,
partial=设置True,必须的字段都变为选填字段
)
注:partial设置True的本质就是使字段 required=True 校验规则失效

1.单整体改:

# 单整体修改:对 v2/books/(pk)/ 传的数据是与model对应的字典{name|price|publish|authors}
def put(self, request, *args, **kwargs):
# 数据
request_data = request.data
# 被修改model类对象的pk
pk = kwargs.get('pk')
# 先拿到被修改的model类对象,再利用反序列化校验request_data数据
book_obj = models.Book.objects.filter(pk=pk).first()
if book_obj is None:
return Response({
'status': 1,
'msg': '参数错误',
})
# 目的:将众多数据的校验交给序列化类来处理 - 让序列化类扮演反序列化角色,校验成功后,序列化类来帮你入库
book_ser = serializers.V2BookModelSerializer(
instance=book_obj, # instance是要被修改的对象,有这个参数就是修改,没有就是增加
data=request_data, # 参与反序列化校验的数据信息
partial=False, # partial默认就是False,意思是每个必须字段都要有,也就是整体改,反之是局部改
)
# 校验
book_ser.is_valid(raise_exception=True)
# 校验通过后利用save()方法,调用ModelSerializer中的update方法自动完成单个整体修改
book_ser.save()
return Response({
'status': 0,
'msg': 'ok',
'results': serializers.V2BookModelSerializer(instance=book_obj).data # instance=book_obj 也可以只写book_obj,默认就是传给instance
})

2.单与群 的 整体/局部修改 ListSerializer

  • serializers.py文件中

from rest_framework.serializers import ListSerializer
# 重点:ListSerializer与ModelSerializer建立关联的是:ModelSerializer的Meta类的 - list_serializer_class

class V2BookListSerializer(ListSerializer):
def update(self, instance, validated_data):
print(instance) # 要更新的model类对象们,如Book表的一条条记录
print(validated_data) # 更新的model对象对应的数据们(前端传来的)
print(self.child) # 服务的模型序列化类 (这里是:V2BookModelSerializer)
for index, obj in enumerate(instance):
# drf框架没有群改实现体,调用的是ModelSerializer的update
self.child.update(obj, validated_data[index])
return instance # 原模型序列化类变化
class V2BookModelSerializer(ModelSerializer):
class Meta:
# 群改,需要设置 自定义ListSerializer,重写群改的 update 方法
list_serializer_class = V2BookListSerializer
...
  • 视图层

# 单局部改:对 v2/books/(pk)/ 传的数据,数据字段key都是选填
# 群局部改:对 v2/books/
# 请求数据 - [{pk:1, name:123}, {pk:3, price:7}, {pk:7, publish:2}]
def patch(self, request, *args, **kwargs):
request_data = request.data
pk = kwargs.get('pk')

# 将单改,群改的数据都格式化成 pks=[需要的对象主键标识] | request_data=[每个要修改的对象对应的修改数据]
if pk and isinstance(request_data, dict): # 单局部改
pks = [pk,]
request_data = [request_data,]
elif not pk and isinstance(request_data, list): #群局部改
# 拿到pk
pks = []
for dic in request_data: # 遍历前台数据[{pk:1, name:123}, {pk:3, price:7}, {pk:7, publish:2}],拿一个个字典
pk = dic.pop('pk', None) # 若前台没有传pk,要指定None
if pk:
pks.append(pk)
else:
return Response({
'status': 1,
'msg': '数据有误',
})
else:
return Response({
'status': 1,
'msg': '数据有误',
})

# pks与request_data数据筛选,
# 1)将pks中的没有对应数据的pk与数据已删除的pk移除,request_data对应索引位上的数据也移除
# 2)将合理的pks转换为 objs
objs = []
new_request_data = []
for index, pk in enumerate(pks):
try:
# 拿到pk对应的合理model对象,并存储
obj = models.Book.objects.get('pk')
objs.append(obj)
# 对应索引的数据就需要保存下来
new_request_data.append(request_data[index])
except:
continue
book_ser = serializers.V2BookModelSerializer(
instance=objs,
data=new_request_data,
partial=True, # 字段任意 群局部改和群整体改都可以
many=True,
)
book_ser.is_valid(raise_exception=True)
book_objs = book_ser.save() # update与create 都会返回对应的model对象
return Response({
'status': 0,
'msg': 'ok',
'results': serializers.V2BookModelSerializer(book_objs, many=True).data
})

总结:

1、整体修改与局部修改
# 序列化
ser_obj = ModelSerializer(model_obj)
# 反序列化,save() => create()
ser_obj = ModelSerializer(data=model_data)
# save() => update()
ser_obj = ModelSerializer(instance=model_obj,data=model_data)
# partial=True => 匹配字段required=True校验条件
ser_obj = ModelSerializer(instance=model_obj,data=model_data,partial=True) 、群改ListSerializer
ser_obj = ModelSerializer(instance=model_obj,data=model_data,partial=True,many=True) # 一旦设置了many=True,反序列化情况下的create、update就不再调用ModelSerializer的
# 而是调用 ModelSerializer.Meta.list_serializer_class 指向的 ListSerializer 类的create、update
# ListSerializer默认只实现了群增的create,要实现群改,必须重写update class MyListSerializer(ListSerializer):
def update(self, instance, validated_data):
# print(instance) # 要更新的对象们: [obj1, obj2, ...]
# print(validated_data) # 更新的对象对应的数据们: [{}, {}, ...]
# print(self.child) # 服务的模型序列化类 - V2BookModelSerializer
for index, obj in enumerate(instance):
self.child.update(obj, validated_data[index])
return instance class MyModelSerializer(ModelSerializer):
class Meta:
# ...
list_serializer_class = MyListSerializer 将两者类建立关联,在MyListSerializer中就可以用self.child拿到MyModelSerializer,进而使用MyModelSerializer中封装好的方法
cls.Meta.list_serializer_class.child = cls

Serializer与ModelSerializer区别:

序列化:
Serializer:

- 1. 序列化的字段数量可随意,单要与表中字段名对应
- 2. 自定义序列化属性:
gender = serializers.SerializerMethodField()
def get_gender(self, obj): # obj是对应表中的一条记录(即:对象)
# choice类型的解释型值 get_字段_display() 来访问
return obj.get_sex_display()

icon = serializers.SerializerMethodField()
def get_icon(self, obj):
# settings.MEDIA_URL: 自己配置的 /media/,给后面高级序列化与视图类准备的
# obj.icon不能直接作为数据返回,因为内容虽然是字符串,但是类型是ImageFieldFile类型
return '%s%s%s' % (r'http://127.0.0.1:8000', settings.MEDIA_URL, str(obj.icon))

ModelSerializer:

- 1. class Meta类中关联序列化表,字段采用插拔式在fields中注册
- 2. 自定义序列化字段:
该方式设置的序列化字段,必须在fields中声明
publish_address = SerializerMethodField()
def get_publish_addr(self, obj):
return obj.publish.address model类中自定义序列化字段
@property
def publish_name(self):
return self.publish.name # 利用跨表查询返回publish的name
@property
def author_list(self):
return self.authors.values('name', 'detail__mobile')

反序列化:
Serializer:

- 1. 可使用局部钩子和全局钩子
- 2.
类似froms组件的单字段校验规则,不满足时采用局部钩子
name = serializers.CharField(
  max_length=64,
  min_length=3,
  error_messages={
    'max_length': '太长',
    'min_length': '太短'
  }
  )
create,update 自定义, 序列化对象.save()时会调用

ModelSerializer:

- 1. 可使用局部钩子和全局钩子
- 2.
extra_kwargs 用来完成反序列化字段的 系统校验规则
  extra_kwargs = {
    'name': {
    'required': True,
    'min_length':1,
    'error_messages': {'required':'必填项', 'min_length': '太短',}
  }
  }
ModelSerializer类已经帮我们实现了 create 与 update 方法,序列化对象.save()时会调用,也可以在序列化类中自定义

drf框架 - 序列化组件 | ModelSerializer (查,增,删,改)的更多相关文章

  1. 第三章、drf框架 - 序列化组件 | Serializer

    目录 第三章.drf框架 - 序列化组件 | Serializer 序列化组件 知识点:Serializer(偏底层).ModelSerializer(重点).ListModelSerializer( ...

  2. drf框架 - 序列化组件 | Serializer

    序列化组件 知识点:Serializer(偏底层).ModelSerializer(重点).ListModelSerializer(辅助群改) 序列化与反序列化 序列化: 将对象序列化成字符串用户传输 ...

  3. drf框架serializers中ModelSerializer类简化序列化和反序列化操作

    0905自我总结 drf框架serializers中ModelSerializer类 基于seriallizer类进行简化 https://www.cnblogs.com/pythonywy/p/11 ...

  4. DRF的序列化组件

    目录 DRF的序列化组件 Serializer组件 序列化 反序列化 ModelSerializer组件 序列化和反序列化 自定义Response方法 基表相关 DRF中ORM的多表关联操作 外键设计 ...

  5. drf框架序列化和返序列化

    0903自我总结 drf框架序列化和反序列化 from rest_framework import serializers 一.自己对于序列化和反序列化使用的分类 前后端交互主要有get,post,p ...

  6. iOS FMDB的使用(增,删,改,查,sqlite存取图片)

    iOS FMDB的使用(增,删,改,查,sqlite存取图片) 在上一篇博客我对sqlite的基本使用进行了详细介绍... 但是在实际开发中原生使用的频率是很少的... 这篇博客我将会较全面的介绍FM ...

  7. iOS sqlite3 的基本使用(增 删 改 查)

    iOS sqlite3 的基本使用(增 删 改 查) 这篇博客不会讲述太多sql语言,目的重在实现sqlite3的一些基本操作. 例:增 删 改 查 如果想了解更多的sql语言可以利用强大的互联网. ...

  8. 好用的SQL TVP~~独家赠送[增-删-改-查]的例子

    以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQL性能优化.  本系列主要是针对T-SQL的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础] ...

  9. ADO.NET 增 删 改 查

    ADO.NET:(数据访问技术)就是将C#和MSSQL连接起来的一个纽带 可以通过ADO.NET将内存中的临时数据写入到数据库中 也可以将数据库中的数据提取到内存中供程序调用 ADO.NET所有数据访 ...

随机推荐

  1. 基于travis和git tag 实现npm自动化发版

    最近又把烂尾的开源项目alfred-femine拾起来了,这个项目旨在开发一系列前端常用的alfred workflow,提供前端开发的查询效率.时隔这么久,再次搞起,希望自己能够一直维护下去,也欢迎 ...

  2. day31——recv工作原理、高大上版解决粘包方式、基于UDP协议的socket通信

    day31 recv工作原理 源码解释: Receive up to buffersize bytes from the socket. 接收来自socket缓冲区的字节数据, For the opt ...

  3. python 读取环境变量

    python 读取环境变量 前言 在使用python时候千万不要把账户密令直接写入脚本,特别是当你计划开源自己的作品时. 为了保护账户信息,你需要让脚本从环境中导入敏感信息. 读取方法 import ...

  4. golang方法和函数的区别

  5. 【scratch3.0教程】2.1 涂鸦花朵

    第4课    涂鸦花朵 1.编程前的准备 在设计一个作品之前,必须先策划一个脚本,然后再根据脚本,收集或制作素材(图案,声音等)接着就可以启动Scratch,汇入角色,舞台,利用搭程序积木的方式编辑程 ...

  6. 3.NioEventLoop的启动和执行

    NioEventLoop启动和执行 NioEventLoop启动 在服务端启动的代码中,我们看到netty在注册和绑定时,判断了当前线程是否是NioEventLoop线程.如果不是, 则将这些操作包装 ...

  7. springboot笔记08——整合swagger2

    Swagger是什么? Swagger是一个RESTFUL 接口的文档在线自动生成和功能测试的框架.利用swagger2的注解可以快速的在项目中构建Api接口文档,并且提供了测试API的功能. Spr ...

  8. JavaScript_day02

    10.随机数 随机数一般和数组组合使用. 生成随机数:使用Math.random()函数,生成的随机数0-1.一般乘以10^n扩大随机数范围. Math.round()函数和parseInt()函数. ...

  9. UCOS内存管理

    STM32F10xxx内置64K字节的静态SRAM.它可以以字节.半字(16位)或全字(32位)访问 SRAM的起始地址是0x20000000 UCOSII //定义存储区 OS_MEM *DATA_ ...

  10. Python基础Day1—下

    六.Python运行 print()   打印命令,输出到屏幕上 操作: 命令提示符-->输入Python-->文件路径 若输入Python回车报错或者提示没有,则Python解释器没有安 ...