DRF学习笔记(1)——准备⼀个DRF项⽬、序列化、关联对象
⽂章⽬录
准备⼀个DRF项⽬
环境搭建
IDE推荐使⽤Pycharm专业版本,专业版相较于免费版本,可以直接连接数据库。学⽣可以直接申请专业版的使⽤。
开发环境我是⽤的Anaconda,需要注意的是安装Django的2.2版本,最新的3.x还属于测试版,与之前的版本使⽤有着区别,也不稳定。另外需要安装djangoresrframework和mysqlclient等包。
项⽬配置
pycharm创建Django项⽬,使⽤先前创建的conda环境。
在setting.py中如下修改
ALLOWED_HOSTS = ['*']
在INSTALLED_APP中添加
INSTALLED_APPS =[
......
'rest_framework'
]
根据需要修改数据库
DATABASES ={
'default':{
'ENGINE':'django.sql',
'NAME':'xxx',
'HOST':'127.0.0.1',
'USER':'xxx',
'PASSWORD':'xxx',
'PORT':3306,
}
}
修改语⾔选项和时区
LANGUAGE_CODE ='zh-hans'
TIME_ZONE ='Asia/Shanghai'
USE_I18N =True
USE_L10N =True
USE_TZ =False
如果设置了数据库,对数据库进⾏连接,连接数据库的前提是体现创建好了数据库。填写数据库的名称,⽤户名,密码。填写完毕可以点击测试连接,如果提⽰TimeZone问题,可以点击⽴即修复。
测试
pycharm窗⼝的Terminal命令⾏下输⼊python manage.py runserver,启动测试。出现下⾯界⾯表⽰配置成功。
数据迁移
- 从数据库到models.py
`python manage.py inspectdb > App/models.py`
Serializer序列化
正向序列化
serializer.py
class BookSerializer(serializers.Serializer):
btitle = serializers.CharField(max_length=100, required=False)
bpub_date = serializers.DateField(allow_null=True, required=False)
bread = serializers.IntegerField(min_value=0)
bcomment = serializers.IntegerField(min_value=0)
bimage = serializers.CharField(max_length=300)
views.py
def get(self, request):
# 正向序列化
books = Bookinfo.objects.all()
bs = BookSerializer(instance=books, many=True)
return Response(data=bs.data)
反向序列化
使⽤serializers.Serializer反向序列化,需要重写 create update
create 是创建新的对象
serializer.py
def create(self, validated_data):
# book = Bookinfo(btitle=('btitle'))
# book.bpub_date = ('bpub_date')
# book.bread = ('bread', 0)
# book.bcomment = ('bcomment', 0)
# book.bimage = ('bimage', '')
# book.save()
# return book
# 也可由下⾯这么写
return ate(**validated_data)
update 是对对象的更新
def update(self, instance, validated_data):
"""
:param instance: 要更新的对象
:
param validated_data: y要更新的属性字典
:return: 对象
"""
print("update")
instance.btitle = ('btitle')if ('btitle')else instance.btitle
if ('bpub_date'):
instance.bpub_date = ('bpub_date')
else:
instance.bpub_date = instance.bpub_date
instance.bread = ('bread')if ('bread')else instance.bread
instance.bcomment = ('bcomment')if ('bcomment')else instancement
instance.bread = ('bimage')if ('bimage')else instance.bimage
instance.save()
return instance
在视图函数views.py中实现操作,如果使⽤序列化器进⾏验证更新操作,需要讲所有的不允许为空的值指定,然后更新,否则会报错。
# 新增操作
book ={'btitle':'庆余年2','bpub_date':'2020-3-10',
'bread':10,'bcomment':30,'bimage':'static/1.jpg'}
bs = BookSerializer(data=book)
# 验证
if bs.is_valid():
# 保存到数据库
# 保存到数据库
bs.save()
print(bs.data)
return Response({'code':0,'msg':'保存成功'})
else:
s)
return Response({'code':1,'msg': bs.errors})
# 更新操作
data ={'bimage':'static/0.jpg'}
book = (pk=3)
# 把对象赋值给instance,更新属性字典赋值给data
bs = BookSerializer(instance=book, data=data)
# 验证
if bs.is_valid():
# 保存到数据库
bs.save()
print(bs.data)
return Response({'code':0,'msg':'保存成功'})
else:
s)
return Response({'code':1,'msg': bs.errors})
进⾏序列化验证更新会有些⿇烦,可以写成部分更新。
views.py
# 部分更新
data ={'bimage':'static/111.jpg'}
book = (pk=3)
for key, value in data.items():
if hasattr(book, key):
setattr(book, key, value)
book.save()
return Response({'code':2,'msg':'update success'})
⾃定义验证器
单独的函数
def check_data(value):
if value < datetime(2010,1,1).date():
raise serializers.ValidationError("⽇期不能⼩于2010-1-1")
bpub_date = serializers.DateField(allow_null=True, required=False, validators=[check_data])
使⽤定义单字段验证,validate_xxx, 验证哪个字段就写对应的名字到xxx,此时的attrs为字符串,不是字典。
def validate_bread(self, attrs):
if attrs >1000:
raise serializers.ValidationError("阅读数不能⼤于1000")
涉及到多字段验证
def validate(self, attrs):
pass
(推荐使⽤)使⽤ModelSerializer进⾏序列化,⾃动⽣成create和update⽅法
class BookSerializer(serializers.ModelSerializer):
bread = serializers.IntegerField(min_value=0)# 重写验证
class Meta:
model = Bookinfo
fields =['btitle','bpub_date','bread','bcomment','bimage']
# fields = '__all__'
关联对象
1.查询到的字典中只包含关联表的主键
related_name 在表中定义外键时,增加related_name字段指定这个字表在主表中对应的外键属性,
models.py
class Bookinfo(models.Model):
btitle = models.CharField(max_length=200)
bpub_date = models.DateField(blank=True, null=True)
bread = models.IntegerField()
bcomment = models.IntegerField()
bimage = models.CharField(max_length=200, blank=True, null=True)
class Meta:
managed =False
db_table ='bookinfo'
class Heroinfo(models.Model):
hid = models.AutoField(primary_key=True)
hname = models.CharField(max_length=50)
bid = models.ForeignKey(Bookinfo, models.DO_NOTHING, db_column='bid', blank=True, null=True, related_name='heros') class Meta:
managed =False
db_table ='heroinfo'
在models.py⾥定义了外键,使⽤了related_name='heros,在序列化器⾥设置关联对象。
serializer.py
class HeroSerializer(serializers.ModelSerializer):
class Meta:
model = Heroinfo
fields ='__all__'
class BookSerializer(serializers.ModelSerializer):
# 关联对象
heros = PrimaryKeyRelatedField(many=True, read_only=True)
bread = serializers.IntegerField(min_value=0)# 重写验证
class Meta:
model = Bookinfo
fields ='__all__'
最后返回字典为,其中heros下为对应字段的主键
2.使⽤⽅法__str__(self),直接返回名字
django怎么学在models.py⾥定义模型的同时,重写⽅法__str__(),序列化器中使⽤StringRelatedField()⽅法可以直接返回名字。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论