rest_framework之序列化组件
什么是rest_framework序列化?
在写前后端不分离的项目时:
我们有form组件帮我们去做数据校验
我们有模板语法,从数据库取出的queryset对象不需要人为去转格式
当我们写前后端分离项目的时:
我们需要自己去做数据校验
我们需要手动去转数据格式,因为跨平台数据传输都用json字符串,不能直接jsonqueryset对象
这个时候你就要想想了,原生django里有这么神奇的组件,那rest_framework里会不会也有这样的组件呢?嗯...果然有!
这就是rest_framework的序列化组件,下面我们一起来看!
怎么用rest_framework的序列化组件?
首先我们需要从rest_framework导几个模块
from rest_framework.serializers import Serializer,ModelSerializer
from rest_framework import serializers
Serializer是rest_framework原生的序列化组件
ModelSerializer是rest_framework在原生的序列化组件的基础上封装了一层的序列化组件
用法:1、在用我们的rest_framework序列化组件的时候,我们的视图层都必须写视图类,不能再写视图函数
2、我们需要针对每一张模型表写一个类来继承Serailizer或者ModelSerailizer类,
当我们在视图类里需要对数据进行序列化或者反序列化的时候,在自己定义的类传入需要序列化的数据实例化,调用.data即可拿到序列化或者校验后的数据了
原生Serializer用法:
详细使用我们来上代码,我们起一个django项目,在app01里面新建myserializer文件,这里面写我们定义的序列化类。
看项目应用目录
路由层
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
# /books/的时候表示获取所有图书, /book/1/ 表示对id为1的图书进行操作
url(r'^book/(?P<id>\w+)/$|(?P<type>books)/$', views.Book.as_view()), # 获取所有出版社信息
url(r'^publish/$', views.Publishs.as_view()), # 对某个出版社进行操作
url(r'^publish/(?P<id>\w+)/$', views.Publish.as_view()), # 作者author部分暂没写
]
模型层
from django.db import models # Create your models here.
from django.contrib.auth.models import User,AbstractUser class UserInfo(AbstractUser):
phone = models.CharField(max_length=15)
avatar = models.FileField(upload_to='static/avatar',default=None) class Book(models.Model):
title = models.CharField(max_length=64)
price = models.DecimalField(max_digits=10,decimal_places=2)
publish_time = models.DateField(null=True)
authors = models.ManyToManyField(to='Author')
publish = models.ForeignKey(to="Publish")
def __str__(self):
return self.title class Author(models.Model):
name = models.CharField(max_length=64)
choices = ((0, '男'), (1, '女'), (2, '保密'))
sex = models.IntegerField(choices=choices)
info = models.CharField(null=True,max_length=255) def __str__(self):
return self.name class Publish(models.Model):
name = models.CharField(max_length=32)
phone = models.CharField(null=True,max_length=15)
address = models.CharField(null=True,max_length=255) def __str__(self):
return self.name
序列化组件层
from rest_framework import serializers
from app01 import models """
使用步骤:
1、新建序列化类,继承Serializer
2、类中定义和模型表一一对应的字段
-其中类中的名字可以改变,需要在serializers.CharField()的括号中指定source=某个字段,建议映射关系
-外键关系的字段可以用serializers.SerializerMethodField(),需要在下方固定写 get_字段名 的方法,
这里可以写具体逻辑,最终返回结果就是该字段的结果
3、当新增数据的时候需要重写父类的create方法,逻辑由自己实现,可以参考下面BookSerilizers类中实现的create方法
4、当修改数据的时候需要重写父类的update方法,逻辑由自己实现,可以参考下面BookSerilizers类中实现的update方法
5、当完成这些配置后就可以在视图类中实例化调用了,序列化的时候序列化,反序列化的时候校验
""" class PublishSerilizers(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
name = serializers.CharField(max_length=32)
phone = serializers.CharField(max_length=15)
address = serializers.CharField(max_length=255) class AuthorSerilizers(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
name = serializers.CharField(max_length=32)
sex = serializers.CharField()
info = serializers.CharField(max_length=255) class BookSerilizers(serializers.Serializer):
id = serializers.IntegerField(read_only=True) #read_only 是指当前字段只读,前端可以不用传 write_only是指不给前端返回这个字段,但是前端新增和修改必须传
title = serializers.CharField(max_length=64)
price = serializers.DecimalField(max_digits=8,decimal_places=2)
publish_time = serializers.DateField()
# publish = serializers.CharField(source="publish.name") # source 参数可以指定当下显示的字段名关联至模型表里的哪个字段名,当指定了以后当前命名的名字就不能和数据库里相应的字段名相同了
publish = serializers.SerializerMethodField(allow_null=True) # SerializerMethodField的方式,然后下面定义get_字段名的方法,即可在方法体写逻辑代码返回你希望得到值
def get_publish(self,obj): # 这里的obj必传,obj是当前循环到的数据对象
res = PublishSerilizers(instance=obj.publish) # 序列化当前数据对象关联的publish表里的相应数据记录
return res.data authors = serializers.SerializerMethodField(allow_null=True)
def get_authors(self,obj):
authors_list = obj.authors.all() # author与book是多对多关系,所以需要.all()取到所有的记录,就是ORM的方法
res = AuthorSerilizers(instance=authors_list,many=True) #由于是序列化多条记录,指定many=True
return res.data def create(self, validated_data):
ret = models.Book.objects.create(**validated_data) # 用Django ORM的操作将视图层传来的数据新增到数据库
return ret def update(self, instance, validated_data): # instance是数据库原来的对象 validated_data是个字典,装的是校验完成后的需要修改的数据
instance.name = validated_data.get("name")
instance.price = validated_data.get("price")
instance.publish_time = validated_data.get("publish_time")
instance.publish_id = validated_data.get("publish_id")
instance.save() # 逐个替换后保存
instance.authors.set(validated_data.get("authors")) # 修改多对多表记录,修改需要用set([1,2,4])的形式
return instance
视图层
from django.shortcuts import render,HttpResponse # Create your views here. 以Book信息为例 from rest_framework.views import APIView,Response
from app01 import models
from app01 import myserializers
from app01 import mymodelSer
class Book(APIView):
def get(self,request,*args,**kwargs):
if kwargs.get("type") == 'books': # 根据路由请求过来的方式来判断是查询所有书籍信息还是一本书的信息,这里是查所有的
books = models.Book.objects.all()
many= True # 指定序列化参数,如果是序列化多条数据就是True
elif kwargs.get("id").isdigit(): # 如果查询携带id,那么就查单本书的
books = models.Book.objects.filter(id=kwargs.get("id")).first() #序列化单条数据的数据要.first()
many = False # 指定序列化参数,如果是序列化单条数据就是True res = myserializers.BookSerilizers(instance=books,many=many) # 将数据库取的queryset对象传入自己定义的序列化类进行序列化
return Response(res.data)
pass def post(self,request,**kwargs):
response = {"status_code":100,"msg":"新增成功!"}
ret = myserializers.BookSerilizers(data=request.data,many=False) #反序列化前端传来的数据
if ret.is_valid(): # 数据校验,当执行这句判断时,才会去做校验
print(ret.validated_data) # 校验后的结果,用ret.validated_data,它会过滤掉不属于模型表字段的键值对,包括前端传来的publish,authors,因为在序列化类里面这两个字段用了SerializerMethodField
ret.validated_data["publish_id"] = request.data.get("publish_id") #在创建book对象前需要手动叫publish字段的键值对添加进去,然后创建book记录
res = ret.create(ret.validated_data) # 这里的create方法调用的是我们在BookSerilizers里面重写的父类的create方法
# 在create的时候必须重写父类的create方法,不然就只能用Django ORM新增,在这里的create里面实际上也是用ORM的新增
res.authors.add(*request.data.get("authors")) #手动用ORM新建多对多第三张表的记录
res.save()
response["data"] = myserializers.BookSerilizers(instance=res).data # res 是数据对象,需要序列化得到数据.data获取
return Response(response)
else:
response["status_code"] = 101
response['msg'] = '新增失败!'
response["data"] = ret.errors # 如果校验不成功,错误信息会自动放在errors里,errors = {"name":"局部错误信息",..."detail":"全局错误信息"}
return Response(response)
pass def put(self,request,**kwargs):
response = {"status_code": 200, "msg": "修改成功!"}
obj = models.Book.objects.filter(id = kwargs.get("id")).first()
ret = myserializers.BookSerilizers(instance=obj,data=request.data, many=False) # 修改时需要将原数据对象和前端传来的将要修改的信息传入BookSerilizers反序列化校验
if ret.is_valid(): # 校验成功时
ret.validated_data['publish_id'] = request.data.get("publish_id")
ret.validated_data['authors'] = request.data.get("authors")
res = ret.update(instance=obj,validated_data=ret.validated_data) # 将数据对象和校验后的结果传入更新
response["data"] = ret.validated_data
return Response(response)
else:
response["data"] = ret.errors
return Response(response)
pass def delete(self,request): pass
Serailizer使用总结:定义序列化类继承Serailizer,类中定义与模型表一一对应的字段,然后再定义局部钩子和全局钩子做校验用,重写create和update方法,最后再视图类中实例化序列化类,通过.data取到序列化后的数据
下面我们来看ModelSerailizer的使用:
路由层
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^publish/$', views.PublishsView.as_view()),
url(r'^publish/(?P<pk>\d+)/$', views.PublishView.as_view()),
url(r'^book/$', views.BooksView.as_view()),
url(r'^book/(?P<pk>\d+)/$', views.BookView.as_view()),
url(r'^author/$', views.AuthorsView.as_view()),
url(r'^author/(?P<pk>\d+)/$', views.AuthorView.as_view()), ]
模型层
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.class Publish(models.Model):
name = models.CharField(max_length=32)
phone = models.CharField(max_length=15)
address = models.CharField(max_length=255) class Book(models.Model):
title = models.CharField(max_length=64)
price = models.DecimalField(max_digits=8,decimal_places=2)
publish = models.ForeignKey(to='Publish')
authors = models.ManyToManyField(to='Author') class Author(models.Model):
name = models.CharField(max_length=32)
sex = models.IntegerField(choices=((1,'男'),(0,'女'),(2,'保密')),default=1)
info = models.CharField(max_length=255,default='这人很懒,什么都没写!')
序列化组件层
from rest_framework.serializers import Serializer,ModelSerializer
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from app01 import models """
使用步骤:
1、新建序列化类,继承ModelSerializer
2、类中定义和模型表一一对应的字段,这里可以定义class Meta() 然后指定模型表model和 映射字段fields,比Serializer更简洁
-其中类中的名字可以改变,需要在serializers.CharField()的括号中指定source=某个字段,建议映射关系
-外键关系的字段可以用serializers.SerializerMethodField(),需要在下方固定写 get_字段名 的方法,
这里可以写具体逻辑,最终返回结果就是该字段的结果
3、当新增数据的时候不需要重写父类的create方法,这里ModelSerializer做了封装
4、当修改数据的时候不需要重写父类的update方法,这里ModelSerializer做了封装
5、当完成这些配置后就可以在视图类中实例化调用了,序列化的时候序列化,反序列化的时候校验 """ class PublishSerializer(ModelSerializer):
# 自定义序列化类继承ModelSerializer可以在类里面写class Meta()
class Meta(): # 如果不想每个字段都自己写,那么这就是固定写法,在继承serializer中字段必须自己写,这是二者的区别
model = models.Publish # 指定需要序列化的模型表
fields = ("__all__") # 指定需要校验的字段 "__all__" 表示所有字段,也可以指定字段(字段一,字段二) # exclude = ('name') 和fields用法相反,取除了某个字段以外的字段
# depth = 1 指定数据跨表深度,2 指跨2两张表,外键关系会取到完整信息 def validate_name(self,value): # 局部钩子 validate_加字段名,需要给定形参,这个形参就是字段值
if value.startswith("sb"):
raise ValidationError("出版社名称含有敏感词汇") # 抛出异常,但这个异常是在errors信息中返回给前端,不会在后端报出
return value # 对哪个字段进行校验之后需要将该字段值返回 def validate_phone(self,value):
if not value.isdigit():
raise ValidationError("出版社联系方式不合法!")
return value def validate(self, attrs): # 全局钩子 做全局性的数据校验,attrs即需要校验的数据{"name":'xxx',...}
name = attrs.get("name")
phone = attrs.get("phone")
address = attrs.get("address")
if (not phone) and (not address):
raise ValidationError("出版社联系方式和地址必须选填一项")
return attrs class BookSerializer(ModelSerializer):
class Meta():
model = models.Book
fields = ('title','price','authors','publish') #指定序列化的字段 #加上以下这一段在get请求数据的时候会拿到关联字段的详细信息,但是在存的时候会报错 ---方便取,不方便存,存需要另外定义反序列化类
#如果去掉下面这一段在get请求的时候会拿到关联字段的id返回前端,存的时候不会报错
# =======================================================
authors = serializers.SerializerMethodField()
def get_authors(self,obj):
res = AuthorSerializer(instance=obj.authors.all(),many=True)
return res.data
publish = serializers.SerializerMethodField()
def get_publish(self,obj):
res = PublishSerializer(instance=obj.publish)
return res.data
# ================================================== def validate_title(self,value): # 局部钩子校验
if value.startswith("sb"):
raise ValidationError("书名不能包含敏感词汇")
return value def validate_price(self,value): # 全局钩子校验
if not value:
raise ValidationError("图书价格不能为空!")
try:
float(value)
except ValueError:
raise ValidationError("请输入合法的图书价格!")
return value class AuthorSerializer(ModelSerializer):
class Meta():
model = models.Author
fields = ('name','sex','info')
# 以下如果自定义sex字段的取值内容,取的时候会取到 '男','女','其他',但存的时候会报错
# 如果不自定义的话,取的是数据库存储的内容 1,0,2 存可以直接通过0,1,2去存,也就是前端只需要传sex的数字值即可存
# ============================================================
sex = serializers.CharField(source="get_sex_display")
# ============================================================
视图层
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from app01 import models
from app01.Object_Seriailzers import PublishSerializer,BookSerializer,AuthorSerializer # Create your views here.
#出版社接口 class PublishsView(APIView):
def get(self,request,*args,**kwargs):
response = {"status_code":100,"msg":"查询成功!",'data':""}
queryset = models.Publish.objects.all()
# 对多条数据进行序列化需要制定many=True
ret = PublishSerializer(instance=queryset,many=True)
response['data'] = ret.data
return Response(response)
pass def post(self,request,*args,**kwargs):
response = {"status_code":200,'msg':"新增成功!","data":''}
ret = PublishSerializer(data=request.data)
if ret.is_valid(): # 这里会执行所有的校验,系统及自定义
ret.save() # 这里的保存就会执行数据库的保存,不需要去自己写create方法
response['data'] = ret.data #如果是继承原生的Serailizer,获取到过滤后的数据要通过ret.validated_data取
else:
response["status_code"] = 201
response['msg'] = '新增失败!'
response['data'] = ret.errors
return Response(response) pass class PublishView(APIView): def get(self,request,pk,*args,**kwargs):
response = {"status_code":100,'msg':'查询成功!','data':''}
ret = PublishSerializer(models.Publish.objects.filter(pk=pk).first())
response['data'] = ret.data # 取到序列化后的对象
return Response(response)
pass def put(self,request,pk,*args,**kwargs):
response = {"status_code":200,'msg':'修改成功!','data':''}
# 先查出对象
query = models.Publish.objects.filter(pk=pk).first() # 将数据库对象和前端请求的数据交由PublishSerializer序列化
ret = PublishSerializer(instance=query,data=request.data)
if ret.is_valid(): #判断是否校验通过
# 将数据库对象和前端请求的数据交由update更新,update内部已经封装更新和保存操作
# 如果涉及到多表更新或其他复杂操作,可以在PublishSerializer中自定义update方法,update返回的是更新后的对象
data = ret.update(instance=query,validated_data=ret.validated_data)
# 将修改后的数据返回,注意取ret.data是过滤后的数据,如果是继承原生的Serailizer取过滤后的数据是ret.validated_data取
response['data'] = ret.data
else:
response['status_code'] = 201
response['msg'] = '修改失败!'
response['data'] = ret.errors
return Response(response)
pass def delete(self,request,pk,*args,**kwargs):
response = {'status_code':200,'msg':'删除成功!'}
models.Publish.objects.filter(pk=pk).first().delete()
return Response(response)
pass # 图书接口
class BooksView(APIView): def get(self, request,*args,**kwargs):
response = {"status_code":200,'msg':'查询成功!','data':''}
queryset = models.Book.objects.all()
ret = BookSerializer(instance=queryset,many=True)
response['data'] = ret.data
return Response(response) pass def post(self, request,*args,**kwargs):
response = {"status_code": 200, 'msg': '新增成功!', 'data': ''}
ret = BookSerializer(data=request.data)
if ret.is_valid():
obj = ret.save()
response['data'] = ret.data
else:
response['status_code'] = 201
response['msg'] = '新增失败!'
response['data'] = ret.errors
return Response(response)
pass class BookView(APIView): def get(self, request,pk,*args,**kwargs):
response = {"status_code": 200, 'msg': '查询成功!', 'data': ''}
ret = BookSerializer(instance=models.Book.objects.filter(pk=pk).first())
response['data'] = ret.data
return Response(response)
pass def put(self, request,pk):
response = {"status_code": 200, 'msg': '更新成功!', 'data': ''}
query = models.Book.objects.filter(pk=pk).first()
ret = BookSerializer(instance=query,data=request.data)
if ret.is_valid(): # 这里的if也可以不需要,只需要在is_valid()中配置raise_exception=True即可,
# 如果校验不通过,内部会直接返回错误信息给前端,下面代码不会走
obj = ret.save()
response['data'] = BookSerializer(instance=obj).data
else:
response['status_code'] = 201
response['msg'] = '更新失败!'
response['data'] = ret.errors
return Response(response) pass def delete(self, request,pk):
response = {"status_code": 200, 'msg': '删除成功!', 'data': ''}
models.Book.objects.filter(pk=pk).first().delete()
return Response(response)
pass # 作者接口
class AuthorsView(APIView):
def get(self,request):
response = {"status_code": 200, 'msg': '查询成功!', 'data': ''} queryset = models.Author.objects.all()
ret = AuthorSerializer(instance=queryset,many=True)
response['data'] = ret.data
return Response(response)
pass def post(self,request):
response = {"status_code": 200, 'msg': '新增成功!', 'data': ''} ret = AuthorSerializer(data=request.data)
if ret.is_valid():
obj = ret.save()
response['data'] = AuthorSerializer(instance=obj).data
else:
response['msg'] = '新增失败!'
response['data'] = ret.errors
return Response(response)
pass class AuthorView(APIView):
def get(self,request,pk,*args,**kwargs):
response = {"status_code": 200, 'msg': '查询成功!', 'data': ''}
ret = AuthorSerializer(instance=models.Author.objects.filter(pk=pk).first())
response['data'] = ret.data
return Response(response)
pass def put(self,request,pk,*args,**kwargs):
response = {"status_code": 200, 'msg': '更新成功!', 'data': ''}
query = models.Author.objects.filter(pk=pk).first()
ret = AuthorSerializer(instance=query, data=request.data)
if ret.is_valid():
obj = ret.save()
response['data'] = ret.data
else:
response['status_code'] = 201
response['msg'] = '更新失败!'
response['data'] = ret.errors
return Response(response)
pass
def delete(self,request , pk, *args, **kwargs):
response = {"status_code": 200, 'msg': '删除成功!', 'data': ''}
models.Author.objects.filter(pk=pk).first().delete()
return Response(response)
pass
ModelSerailizer总结: 在Serailizer的基础上进行了进一步的封装,主要体现在3个地方:
1、在序列化类中定义字段不需要全部都自己定义映射关系,只需要配置class Meta 里的模型表model 和字段fields
2、在存和修改的时候不需要在序列化类中实现父类的create和update方法,ModelSerailizer已经做了封装,当然,这是只针对单表的操作,如果涉及多表的操作,我们也可以自己重写create和update方法
3、在校验数据成功后只需要通过ret.save()即可执行create操作,ret.update即可执行更新操作
这里的坑点:
其实在代码里也总结了,当我们在用SerailizerMethodField()时,可以通过定义方法序列化数据库的关联表数据,加上我们自己的逻辑并得到返回值,但是这样会带来一个问题,在反序列化的时候校验会把这些字段的数据过滤掉,导致create和update出现报错,当然我们可以通过将这些数据添加到validated_data中来达到目的,但这终究不是完美的解决办法,小编才疏学浅,还望有大神路过指点一二
rest_framework之序列化组件的更多相关文章
- django rest_framework Serializers 序列化组件
为什么要用序列化组件 当我们做前后端分离的项目~~我们前后端交互一般都选择JSON数据格式,JSON是一个轻量级的数据交互格式. 那么我们给前端数据的时候都要转成json格式,那就需要对我们从数据库拿 ...
- Django1.0和2.0中的rest_framework的序列化组件之超链接字段的处理
大家看到这个标题是不是有点懵逼,其实我就是想要一个这样的效果 比如我get一条书籍的数据,在一对多的字段中我们显示一个url,看起来是不是很绚! 下面我们就来实现这么一个东西 首先我们一对多字段中的一 ...
- Django的rest_framework的序列化组件之serializers.ModelSerializer介绍
这里的介绍的serializers.ModelSerializer就和我们之前学习的modelform一样 serializers.ModelSerializer如下几个功能 1.序列化queryse ...
- Django的rest_framework的序列化组件之序列化多表字段的方法
首先,因为我们安装了restframework,所以我们需要在django的settings中引入restframework INSTALLED_APPS = [ 'django.contrib.ad ...
- 2 APIView与序列化组件
1.入门 1.1 参考blog 官方文档:http://www.django-rest-framework.org/tutorial/quickstart/#quickstart yuan的Blog: ...
- DRF 序列化组件 模型层中参数补充
一. DRF序列化 django自带有序列化组件,但是相比rest_framework的序列化较差,所以这就不提django自带的序列化组件了. 首先rest_framework的序列化组件使用同fr ...
- django rest_framework 序列化组件详解
为什么要用序列化组件 当我们做前后端分离的项目,我们前后端交互一般都选择JSON数据格式,JSON是一个轻量级的数据交互格式. 那么我们给前端数据的时候都要转成json格式,那就需要对我们从数据库拿到 ...
- rest_framework序列化组件
一.Django自带的序列化组件 ==>对象序列化成json格式的字符串 from django.core import serializers from django.core import ...
- rest_framework之ModelViewSet、路由控制、序列化组件快速搭建项目雏形
以UserInfo表登陆接口为例 ModelViewSet的用法十分简单,定义一个视图类,指定一个模型表,指定一个序列化类即可帮我们完成增删改查等功能 示例: # 视图层 from app01.MyS ...
随机推荐
- PHP mmysqli_affected_rows(connection);函数
mysqli_affected_rows(); 函数返回前一次 MySQL 操作所影响的记录行数. mysqli_affected_rows(connection); connection 必需.规定 ...
- Vue项目中的文件/文件夹命名规范
Vue项目中的文件/文件夹命名规范 0.2262018.09.21 16:01:09字数 820阅读 6979 文件或文件夹的命名遵循以下原则: index.js 或者 index.vue,统一使用小 ...
- fckeditor实现ctrl+v粘贴word图片并上传
tinymce是很优秀的一款富文本编辑器,可以去官网下载.https://www.tiny.cloud 这里分享的是它官网的一个收费插件powerpaste的旧版本源码,但也不影响功能使用. http ...
- Bzoj 3631: [JLOI2014]松鼠的新家(树链剖分+线段树)
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MB Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个 ...
- error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const
类中包含信号槽在在类的声明中一定得使用Q_OBJECT.当编译出现问题上述问题时. 解决方法: 1.删除项目中的头文件以及源文件,再添加. 2.在头文件中对该类进行声明,不是使用class mycla ...
- 删数问题(SDUT2072 )
删数问题 Time Limit: 1000 msMemory Limit: 65536 KiB Problem Description 键盘输入一个高精度的正整数n(≤100位),去掉其中任意s个数字 ...
- ios高版本中select的option选项内容不显示问题
<select class="form-control" @change="inputChange(item.id,postObj[item.id])" ...
- Rand工具类
这篇文章已经废弃. 实际开发中,这个工具类用到得非常少. RandN是主要类,用于生成指定位数的随机字符串,具体功能在这个类中实现 Rand8是修饰了RandN中每个对外方法的修饰类,用与生成8位的随 ...
- git修改下载地址
git查看远程地址git remote -v修改git remote set-url origin [url]
- Flume-自定义 Source
Source 是负责接收数据到 Flume Agent 的组件. Source 组件可以处理各种类型.各种格式的日志数据,包括 avro.thrift.exec.jms.spooling direct ...