这是我的模特:
class Order(models.Model):
"""
订单
"""
order_num = models.CharField(max_length=128, unique=True) # 订单编号
order_status = models.CharField(max_length=12) # 订单状态 "未支付", "已支付,未完成", "已完成", "已经删除","其他"
product_describe = models.TextField() # 产品描述
billing_type = models.CharField(max_length=16) # 计费类型
buytime = models.CharField(max_length=16) # 比如:1月 永久
count = models.IntegerField() # 购买数量
paytype = models.CharField(max_length=16) # 支付方式(支付包,微信,xxx)
cost = models.DecimalField(max_digits=8, decimal_places=2, default=0.00) # 费用(需要花费多少钱)
account = models.ForeignKey(to=Account) # 所属账户
ctime = models.DateTimeField(auto_now_add=True) # 创建时间
uptime = models.DateTimeField(auto_now=True) # 更新时间
def __str__(self):
return self.product_describe
def __unicode__(self):
return self.product_describe
这是我的序列化器:
class OrderCreateSerializer(ModelSerializer):
data_params = serializers.DictField() # 根据产品数据模型不同而异
class Meta:
model = Order
fields = (
"product_describe", # 产品描述 (购买xx产品 + 参数)
"billing_type", # 计费类型 ("包年包月")
# "buytime", # "购买时间"
# "count", # 数量
# "paytype", # 支付方式
"data_params", # 数据
)
def create(self, validated_data):
request = self.context.get("request")
if request and hasattr(request, "user"):
user = request.user
validated_data["order_num"] = generateOrderNum(userid=user.id)
validated_data["order_status"] = "未支付"
data_dic = validated_data.pop("data_params") #
validated_data["buytime"] = data_dic["data"]["buytime"]
validated_data["count"] = data_dic["data"]["count"]
validated_data["paytype"] = "" # 支付类型
validated_data["cost"] = 0.00 # 所需钱
validated_data["account"] = user.account # 是哪个账户
return Order.objects.create(**validated_data)
你知道,在我的序列化程序中,我弹出了data_params
:
data_dic = validated_data.pop("data_params")
但是当我访问此API时,我得到:
/ api / financialmanage / order / add /
的AttributeError 尝试在序列化程序data_params
上获取字段OrderCreateSerializer
的值时出现AttributeError 序列化程序字段可能名称不正确,并且与Order
实例上的任何属性或键都不匹配 原始例外文字是:'订单'对象没有属性' data_params'。
如果我不弹出data_params
,我会收到以下错误:
/ api / financialmanage / order / add /
的TypeError ' data_params'是此函数的无效关键字参数
修改
我的views.py:
class OrderSerializerCreateAPIView(CreateAPIView):
"""
create Order
"""
serializer_class = OrderCreateSerializer
permission_classes = []
queryset = Order.objects.all()
修改-2
就我而言,data_params
词典对我来说是必要的。
因为当我购买具有计数,vcpus,ram,磁盘和带宽的产品(例如CloudServer)时,我通过data_params
来获取它。
您可能想知道为什么我必须使用data_params
来接收数据,因为产品可能不同,如果产品是Wine,它现在不能拥有vcpus属性。
答案 0 :(得分:0)
class OrderCreateSerializer(ModelSerializer):
data_params = DictField(child=serializers.CharField())
.
.
.
def create(self, validated_data):
print(validated_data)
data_dic = validated_data.pop("data_params")
print(data_dic)
return super(OrderCreateSerializer, self).create(validated_data)
class OrderSerializer(ModelSerializer):
class Meta:
model = Order
fields = '__all__'
# by @Vasil Shtiliyanov if you want return data_parms after create
def to_representation(self, instance):
serialized_data = super(OrderSerializer, self).to_representation(instance)
serialized_data['data-params'] = #logic goes here
return serialized_data
class OrderSerializerCreateAPIView(CreateAPIView):
"""
create Order
"""
serializer_class = OrderCreateSerializer
permission_classes = []
queryset = Order.objects.all()
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
instance = self.perform_create(serializer)
data = OrderSerializer(instance).data
headers = self.get_success_headers(data )
return Response(data , status=status.HTTP_201_CREATED, headers=headers)
def perform_create(self, serializer):
return serializer.save()
答案 1 :(得分:0)
如果要在序列化程序不是模型中的字段时将data-params参数添加到序列化程序,则应使用DRF的def to_representation
函数。应该看起来像这样:
def to_representation(self, instance):
serialized_data = super(SerializerClass, self).to_representation(instance)
serialized_data['data-params'] = #logic goes here
return serialized_data
从Meta类的fields参数中删除data-params。
答案 2 :(得分:0)
我对您的解决相同:
data_params = serializers.DictField() # yours
data_params = serializers.DictField(write_only=True) # try it, pls.
源代码:
# rest_framework/serializers.py => L504
def to_representation():.
..
fields = self._readable_fields # this function rest_framework/serializers.py=>L371
...