个人中心续
用户留言功能
以下代码两个问题:
- 为什么序列化的id创建时不需要输入而读取时能直接输出
- add_time 的read_only,和格式化
class LeavingMsgSerializer(serializers.ModelSerializer):
user = serializers.HiddenField(
default=serializers.CurrentUserDefault()
)
add_time = serializers.DateTimeField(read_only=True, format="%Y-%m-%d %H:%M:%S")
class Meta:
model = UserLeavingMessage
fields = ("id", "user", "msg_type", "subject", "message", "file", "add_time")
注释掉此行又没有出错了,不知道为什么,下次记录下错误栈
个人觉得好的习惯还是采用下面这行代码,然后get_queryset直接调用该属性,这样代码会更有结构
queryset = UserFav.objects.all() # 之前可能由于某些第三方包的依赖问题此行需要保留
收货地址功能
用戶收货地址功能。
1.model中更改字段以适应前端;
2.验证手机号码的validate;隐藏user使无法指定user值;
3.view中指定用户权限=>对应主要是非安全方法->应该不包括创建方法;
4.创建在serializer中指定当前用户;
5.get方法在get_queryset中指定用户。
----------------------写得真乱
购物车
加入购物车
此处不使用modelserializer,因为该类会验证unique_together字段,然而更新时该字段是存在的,验证会报错。暂时没理解。最好看一遍源码。
*******************************model中*******************************
unique_together = ("user", "goods")
*******************************serializer中*******************************
class ShopCartSerializer(serializers.Serializer):
user = serializers.HiddenField(
default=serializers.CurrentUserDefault()
)
nums = serializers.IntegerField(required=True, min_value=1, label="数量",
error_messages={
"min_value": "商品数量不能小于1",
"required": "请填写购买数量",
})
goods = serializers.PrimaryKeyRelatedField(queryset=Goods.objects.all(), required=True, label="商品")
def create(self, validated_data):
user = self.context["request"].user
nums = validated_data["nums"]
goods = validated_data["goods"]
existed = ShoppingCart.objects.filter(user=user, goods=goods)
if existed:
existed = existed[0]
existed.nums += nums
existed.save()
else:
existed = ShoppingCart.objects.create(**validated_data)
return existed
修改商品数量
def update(self, instance, validated_data):
# 修改商品数量
# 为什么此处直接是实例,猜测和retrieve方法相关。
instance.nums = validated_data["nums"]
instance.save()
return instance
以下两句代码分别提供了read和list功能,更具体的细节需要查看源码,此处只是提供了一个相当于配置的功能
lookup_field = "goods_id" # retrieve方法
def get_queryset(self): # list方法
return ShoppingCart.objects.filter(user=self.request.user)
vue联调
detailserializer中外键goods实例化goods = GoodsSerializer(many=False)
动态加载serializer
def get_serializer_class(self):
if self.action == "list":
return ShopCartDetailSerializer
else:
return ShopCartSerializer
前端header组件删除商品需要手动更新,结生成订单页面手动输入数量需要点击+或者-号才能真正完成更新。
订单
订单列表和订单删除
serializer
class OrderSerializer(serializers.ModelSerializer):
# 个人猜测此属性只是隐藏,并设置默认值,并不能防止权限,权限由其他设置搞定
user = serializers.HiddenField(
default=serializers.CurrentUserDefault()
)
pay_status = serializers.CharField(read_only=True)
trade_no = serializers.CharField(read_only=True)
order_sn = serializers.CharField(read_only=True)
pay_time = serializers.DateTimeField(read_only=True)
def generate_order_sn(self):
# 当前时间+user_id+随机数
random_ins = Random()
order_sn = "{time_str}{user_id}{ran_str}".format(time_str=time.strftime("%Y%m%d%H%M%S"),
user_id=self.context["request"].user.id,
ran_str=random_ins.randint(10, 99))
return order_sn
def validate(self, attrs):
attrs["order_sn"] = self.generate_order_sn()
return attrs
class Meta:
model = OrderInfo
fields = "__all__"
viewset
class OrderViewset(mixins.ListModelMixin,
mixins.CreateModelMixin,
mixins.DestroyModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet): # 订单不允许修改,所以不继承modelviewset
"""
订单管理
list:
获取个人订单
delete:
删除订单
create:
新增订单
"""
authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication) # 对象级别认证
permission_classes = (permissions.IsAuthenticated, IsOwnerOrReadOnly) # 验证是否为登录用户,拥有的用户。
serializer_class = OrderSerializer
def get_queryset(self): # list方法
return OrderInfo.objects.filter(user=self.request.user
def perform_create(self, serializer): # 生成订单,增加订单商品,清空购物车,
order = serializer.save()
shop_carts = ShoppingCart.objects.filter(user=self.request.user)
for shop_cart in shop_carts:
order_goods = OrderGoods()
order_goods.goods = shop_cart.goods
order_goods.goods_num = shop_cart.nums
order_goods.order = order
order_goods.save()
shop_cart.delete()
return order
订单详情完成
动态加载serializer。serializer类内嵌serializer类。relate_name跟前台有很大关系,同时和serializer的嵌套也有很大关系。
related_name很重要的一个属性
class OrderGoods(models.Model):
# 此处related_name用于serializer实例化嵌套serializer,从而和前端适配,所以此处需要和前端适配。
order = models.ForeignKey(..., related_name="goods", verbose_name='订单信息')
serializer
class OrderGoodsSerializer(serializers.ModelSerializer):
goods = GoodsSerializer(many=False)
class Meta:
model = OrderGoods
fields = "__all__"
class OrderDetailSerializer(serializers.ModelSerializer):
goods = OrderGoodsSerializer(many=True)
class Meta:
model = OrderInfo
fields = "__all__"
viewset中动态加载
def get_serializer_class(self):
if self.action == "retrieve":
return OrderDetailSerializer
else:
return OrderSerializer
网友评论