多对多通过字段序列化
ManyToMany Through Field Serialization
我在使用数量序列化我的 items/orders 时遇到问题。
我得到的结果:
{
"id": 1,
"_current_status": null,
"orderitem_set": [
{
"item_id": 2,
"quantity": 5
},
{
"item_id": 1,
"quantity": 1
}
],
"items": [
{
"id": 2,
"name": "Blue Shoe",
"description": "Sweet blue shoe bro",
"weight": "99.99",
"price": "99.99"
},
{
"id": 1,
"name": "Red Shoe",
"description": "sweet red shoe bro",
"weight": "1.00",
"price": "100.00"
}
],
"_last_modified": "2015-06-10T22:32:08.007833Z",
"_weight": "500.95",
"_total_price": "599.95",
"placed": false,
"date_placed": null
}
我想要的结果:
{
"id": 1,
"_current_status": null,
"items": [
{
"id": 2,
"name": "Blue Shoe",
"description": "Sweet blue shoe bro",
"weight": "99.99",
"price": "99.99",
"quantity": 5
},
{
"id": 1,
"name": "Red Shoe",
"description": "sweet red shoe bro",
"weight": "1.00",
"price": "100.00",
"quantity": 1
}
],
"_last_modified": "2015-06-10T22:32:08.007833Z",
"_weight": "500.95",
"_total_price": "599.95",
"placed": false,
"date_placed": null
}
类
class Order(models.Model):
_current_status = models.ForeignKey("main.Status", blank=True, null=True)
_last_modified = models.DateTimeField(auto_now=True)
_weight = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
_total_price = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
user = models.ForeignKey("main.ShopUser")
items = models.ManyToManyField("main.Item", through='main.OrderItem')
placed = models.BooleanField(default=False)
date_placed = models.DateTimeField(null=True, blank=True)
class OrderItem(models.Model):
order = models.ForeignKey('main.Order')
item = models.ForeignKey('main.Item')
quantity = models.IntegerField(default=1)
序列化程序
我意识到我的序列化程序是将 orderitem_set
放入我的 json 中的原因,但我不知道如何将 quantity
数据放入 items
除了循环遍历项目和 orderitem_set
并向项目添加 quantity
的自定义视图。但这太糟糕了,我希望有一种方法可以使用框架的内置内容来做到这一点,或者至少做到这一点,这样我就不必为每个视图都这样做了。
class OrderItemField(serializers.RelatedField):
def to_representation(self, value):
return {'item_id': value.item_id, 'quantity': value.quantity}
class OrderSerializer(serializers.ModelSerializer):
_current_status = StatusSerializer(required=False, many=False)
orderitem_set = OrderItemField(read_only=True, many=True)
items = ItemSerializer(required=True, many=True)
class Meta:
model = Order
exclude = ('user',)
风景
这种观点给了我我正在寻找的东西,但它太糟糕了。特别是当我有其他观点会给我一个订单列表而不是一个订单时。
def set_quantities(data):
# Gets the quantity for each item and then appends it to each item instead of having 'orderitem_set'
for order_item in data['orderitem_set']:
for item in data['items']:
if item['id'] == order_item['item_id']:
item['quantity'] = order_item['quantity']
del data['orderitem_set']
return data
def get(self, request, *args, **kwargs):
serializer = self.get_serializer(self.get_object())
data = set_quantities(serializer.data)
return Response(data, status=status.HTTP_200_OK)
通过将 OrderSerializer
items
字段更改为 OrderItemField
我可以使用 self.root.instance
返回到根目录 Order
然后使用与作为 Item
实例的 value
结合,构建查询以查找 OrderItem
对象以获取数量。然后我可以使用我的 ItemSerializer
获得序列化的 Item
并将数量附加到该数据。
这样做适用于我所有的订单视图,而且不会那么混乱。如果有更好的方法请告诉我!
序列化程序
class OrderItemField(serializers.RelatedField):
def to_representation(self, value):
if type(self.root.instance) == list:
self.root.instance = self.root.instance[0]
order_item = OrderItem.objects.filter(item=value, order=self.root.instance).first()
quantity = order_item.quantity
value = ItemSerializer(value).data
value['quantity'] = quantity
return value
class OrderSerializer(serializers.ModelSerializer):
_current_status = StatusSerializer(required=False, many=False)
items = OrderItemField(many=True, read_only=True)
class Meta:
model = Order
exclude = ('user',)
你可以这样使用它:
class OrderItemSerializer(serializers.ModelSerializer):
class Meta:
model = Order.items.through
fields = ('order', 'item', 'quantity')
class OrderSerializer(serializers.ModelSerializer):
items = OrderItemSerializer(source='orderitem_set', many=True)
class Meta:
model = Order
fields = ('your_order_fields', 'items')
注意: 您必须将 items
字段添加到 OrderSerializer
。
我在使用数量序列化我的 items/orders 时遇到问题。
我得到的结果:
{
"id": 1,
"_current_status": null,
"orderitem_set": [
{
"item_id": 2,
"quantity": 5
},
{
"item_id": 1,
"quantity": 1
}
],
"items": [
{
"id": 2,
"name": "Blue Shoe",
"description": "Sweet blue shoe bro",
"weight": "99.99",
"price": "99.99"
},
{
"id": 1,
"name": "Red Shoe",
"description": "sweet red shoe bro",
"weight": "1.00",
"price": "100.00"
}
],
"_last_modified": "2015-06-10T22:32:08.007833Z",
"_weight": "500.95",
"_total_price": "599.95",
"placed": false,
"date_placed": null
}
我想要的结果:
{
"id": 1,
"_current_status": null,
"items": [
{
"id": 2,
"name": "Blue Shoe",
"description": "Sweet blue shoe bro",
"weight": "99.99",
"price": "99.99",
"quantity": 5
},
{
"id": 1,
"name": "Red Shoe",
"description": "sweet red shoe bro",
"weight": "1.00",
"price": "100.00",
"quantity": 1
}
],
"_last_modified": "2015-06-10T22:32:08.007833Z",
"_weight": "500.95",
"_total_price": "599.95",
"placed": false,
"date_placed": null
}
类
class Order(models.Model):
_current_status = models.ForeignKey("main.Status", blank=True, null=True)
_last_modified = models.DateTimeField(auto_now=True)
_weight = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
_total_price = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
user = models.ForeignKey("main.ShopUser")
items = models.ManyToManyField("main.Item", through='main.OrderItem')
placed = models.BooleanField(default=False)
date_placed = models.DateTimeField(null=True, blank=True)
class OrderItem(models.Model):
order = models.ForeignKey('main.Order')
item = models.ForeignKey('main.Item')
quantity = models.IntegerField(default=1)
序列化程序
我意识到我的序列化程序是将 orderitem_set
放入我的 json 中的原因,但我不知道如何将 quantity
数据放入 items
除了循环遍历项目和 orderitem_set
并向项目添加 quantity
的自定义视图。但这太糟糕了,我希望有一种方法可以使用框架的内置内容来做到这一点,或者至少做到这一点,这样我就不必为每个视图都这样做了。
class OrderItemField(serializers.RelatedField):
def to_representation(self, value):
return {'item_id': value.item_id, 'quantity': value.quantity}
class OrderSerializer(serializers.ModelSerializer):
_current_status = StatusSerializer(required=False, many=False)
orderitem_set = OrderItemField(read_only=True, many=True)
items = ItemSerializer(required=True, many=True)
class Meta:
model = Order
exclude = ('user',)
风景
这种观点给了我我正在寻找的东西,但它太糟糕了。特别是当我有其他观点会给我一个订单列表而不是一个订单时。
def set_quantities(data):
# Gets the quantity for each item and then appends it to each item instead of having 'orderitem_set'
for order_item in data['orderitem_set']:
for item in data['items']:
if item['id'] == order_item['item_id']:
item['quantity'] = order_item['quantity']
del data['orderitem_set']
return data
def get(self, request, *args, **kwargs):
serializer = self.get_serializer(self.get_object())
data = set_quantities(serializer.data)
return Response(data, status=status.HTTP_200_OK)
通过将 OrderSerializer
items
字段更改为 OrderItemField
我可以使用 self.root.instance
返回到根目录 Order
然后使用与作为 Item
实例的 value
结合,构建查询以查找 OrderItem
对象以获取数量。然后我可以使用我的 ItemSerializer
获得序列化的 Item
并将数量附加到该数据。
这样做适用于我所有的订单视图,而且不会那么混乱。如果有更好的方法请告诉我!
序列化程序
class OrderItemField(serializers.RelatedField):
def to_representation(self, value):
if type(self.root.instance) == list:
self.root.instance = self.root.instance[0]
order_item = OrderItem.objects.filter(item=value, order=self.root.instance).first()
quantity = order_item.quantity
value = ItemSerializer(value).data
value['quantity'] = quantity
return value
class OrderSerializer(serializers.ModelSerializer):
_current_status = StatusSerializer(required=False, many=False)
items = OrderItemField(many=True, read_only=True)
class Meta:
model = Order
exclude = ('user',)
你可以这样使用它:
class OrderItemSerializer(serializers.ModelSerializer):
class Meta:
model = Order.items.through
fields = ('order', 'item', 'quantity')
class OrderSerializer(serializers.ModelSerializer):
items = OrderItemSerializer(source='orderitem_set', many=True)
class Meta:
model = Order
fields = ('your_order_fields', 'items')
注意: 您必须将 items
字段添加到 OrderSerializer
。