一、实现逻辑删除:
is_delete = models.BooleanField(default=False)
dafault = False
二、验证(多属性判断)
def validate(self,attrs):
#能获取多个属性
# attrs表示请求报文中所有的属性与值,类型为字典
def validate_username(self, value):
#获取一个属性
# 2.验证两个密码是否一样
# 获取多属性判断(两个密码) validate(self,attrs):
def validate(self, attrs):
# 判断两个密码是否一致
password = attrs.get('password')
password2 = attrs.get('password2')
if password != password2:
raise serializers.ValidationError('两个密码不一致')
return attrs
#1.验证用户名是否重复
# mobiles/(?P < mobile > 1[3-9]\d{9})/count/$
# value = username count是获取指定用户名数量
def validate_username(self, value):
# 用户名只能是1个或0个
count = User.objects.filter(username=value).count()
if count > 0:
raise serializers.ValidationError('此用户以注册')
return value
get_object(self)
返回详情视图所需的模型类数据对象,默认使用lookup_field参数来过滤queryset。 在试图中可以调用该方法获取详情信息的模型类对象。
若详情访问的模型类对象不存在,会返回404。
该方法会默认使用APIView提供的check_object_permissions方法检查当前对象是否有权限被访问。
class UserDetailView(generics.RetrieveAPIView):
# queryset = User.objects.all()
serializer_class = UserDetailSerializer
# 要求登录:
permission_classes = [IsAuthenticated]
# 视图中封装好的代码,是根据主键查询得到的对象
# 需求:不根据pk查,而是获取登录的用户
# 解决:重写get_object()方法
def get_object(self):
# self.request.user 表示获取当前登录用户,比如获取到当前用户的个人信息
# 获取个人信息不能通过id查询,只能通过当前登录用户查询
return self.request.user
注册序列化器:
write_only=True : 只读 只允许获取 不能写入或者修改
read_only=True : 只写 只能写入或者修改 不能获取
'''注册反序列化'''
class UserCreateSerializer(serializers.Serializer):
# 定义属性
"""
1 .创建用户不需要接收id,也不需要验证,read_only
2. username: 输入 输出 不需要写
3.password: 只输入 write_only
4.password2: 只输入 write_only
5.allow: 只输入 write_only
6.mobile: 输入 输出 不需要写
7.sms_code: 只输入 write_only
"""
id = serializers.IntegerField(read_only=True)
# 输出口令
token = serializers.CharField(read_only=True)
username = serializers.CharField(
min_length=5,
max_length=20,
error_messages={
'min_length': "用户名包含5-20个字符",
'max_length': "用户名包含5-20个字符"
}
)
password = serializers.CharField(
min_length=8,
max_length=20,
error_messages={
'min_length': "密码包含8-20个字符",
'max_length': "密码包含8-20个字符"
},
# 属性只接收客户端的数据,
write_only=True
)
password2 = serializers.CharField(
min_length=8,
max_length=20,
error_messages={
'min_length': "密码包含8-20个字符",
'max_length': "密码包含8-20个字符"
},
write_only=True
)
sms_code = serializers.IntegerField(write_only=True)
mobile = serializers.CharField()
allow = serializers.BooleanField(write_only=True)
视图集中定义附加action动作
在视图集中,除了上述默认的方法动作外,还可以添加自定义动作。
添加自定义动作需要使用rest_framework.decorators.action装饰器。
以action装饰器装饰的方法名会作为action动作名,与list、retrieve等同。
action装饰器可以接收两个参数:
methods: 该action支持的请求方式,列表传递
detail: 表示是action中要处理的是否是视图资源的对象(即是否通过url路径获取主键)
True 表示使用通过URL获取的主键对应的数据对象
False 表示不使用URL获取主键
@action(methods=[‘方法名’],detail=True)
用在用户中心收货地址:修改标题,设置默认
from rest_framework.decorators import action
# 修改标题===>****/pk/title/------put
# 如果没有detail=False=====>*****/title/
# ^ ^addresses/(?P<pk>[^/.]+)/title/$ [name='addresses-title']
@action(methods=['put'], detail=True)
def title(self, request, pk):
# 根据主键查询收货地址
address = self.get_object()
# 接收数据,修改标题属性
address.title = request.data.get('title')
# 保存
address.save()
# 响应
return Response({'title': address.title})
# 设置默认收货地址===>^ ^addresses/(?P<pk>[^/.]+)/status/$ [name='addresses-status']
@action(methods=['put'], detail=True)
def status(self, request, pk):
# 查找当前登录的用户
user = request.user
# 修改属性
user.default_address_id = pk
# 保存
user.save()
# 响应
return Response({'message': 'OK'})