django-tastypie:相关数据未保存
django-tastypie : Related data not saving
我的models.py
class Orders(models.Model):
order_id = models.CharField(max_length=7, primary_key=True)
users = models.ForeignKey(ProductUsers, on_delete=models.DO_NOTHING)
address = models.ForeignKey(ProductUsersAddress, on_delete=models.DO_NOTHING)
payment_method = models.CharField(default='COD', max_length=20, choices=PAYMENT_METHOD)
class OrderedProduct(models.Model):
products = models.ForeignKey(Products, on_delete=models.DO_NOTHING)
orders = models.ForeignKey(Orders, on_delete=models.CASCADE)
quantity = models.IntegerField(default=0)
price = models.DecimalField(default=0.00, max_digits=5, decimal_places=2, blank=False)
我的resources.py
class OrdersResource(ModelResource):
ordered_products = fields.ToManyField('orders.resources.OrderedProductResource',
attribute=lambda bundle: OrderedProduct.objects.filter(orders=bundle.obj),
related_name='orders', full=True, null=True)
contact_no = fields.ForeignKey(ProductUsersResource, 'users')
address = fields.ForeignKey(ProductUsersAddressResource, 'address')
class Meta:
queryset = Orders.objects.all()
resource_name = 'orders'
include_resource_uri = False
collection_name = 'orders'
allowed_methods = ['get', 'post']
always_return_data = True
class OrderedProductResource(ModelResource):
products = fields.ForeignKey(ProductsResource, 'products')
orders = fields.ForeignKey(OrdersResource, 'orders')
class Meta:
queryset = OrderedProduct.objects.all()
resource_name = 'ordered_products'
excludes = ['id']
include_resource_uri = False
我使用 Django-Admin 输入数据。
当我点击时,http://localhost:8000/orders/
,我得到,
{
"orders": [
{
"address": "/api/v1/address/1",
"contact_no": "/api/v1/users/8269661606",
"order_id": "KJLSWI",
"ordered_products": [
{
"orders": "/api/v1/orders/KJLSWI",
"price": "40.00",
"products": "/api/v1/products/1",
"quantity": 2
},
{
"orders": "/api/v1/orders/KJLSWI",
"price": "70.00",
"products": "/api/v1/products/2",
"quantity": 4
},
{
"orders": "/api/v1/orders/KJLSWI",
"price": "67.00",
"products": "/api/v1/products/3",
"quantity": 7
}
],
"payment_method": "COD",
}
]
}
现在根据 tasty 文档,
Tastypie encourages “round-trippable” data, which means the data you
can GET should be able to be POST/PUT’d back to recreate the same
object.
If you’re ever in question about what you should send, do a GET on
another object & see what Tastypie thinks it should look like.
但是当我 post 相同的数据只是改变主键时,
{
"address": "/api/v1/address/1",
"contact_no": "/api/v1/users/8269661606",
"order_id": "ABCDE",
"ordered_products": [
{
"orders": "/api/v1/orders/ABCDE",
"price": "40.00",
"products": "/api/v1/products/1",
"quantity": 2
},
{
"orders": "/api/v1/orders/ABCDE",
"price": "70.00",
"products": "/api/v1/products/2",
"quantity": 4
},
{
"orders": "/api/v1/orders/ABCDE",
"price": "67.00",
"products": "/api/v1/products/3",
"quantity": 7
}
],
"payment_method": "COD",
}
我收到回复,
{
"address": "/api/v1/address/1",
"contact_no": "/api/v1/users/8269661606",
"ordered_products": [],
"payment_method": "COD",
}
我在模型 OrderedProduct
中的数据没有保存。为什么 YYYYYY ??????
试试这个:
def hydrate_m2m(self, bundle):
for ordered_product in bundle.data['ordered_products']:
if isinstance(ordered_product, dict):
ordered_product.update({'orders': bundle.obj})
return super(OrdersResource, self).hydrate_m2m(bundle)
并从 ordered_products
JSON
中删除 orders
键
并将attribute=lambda bundle: OrderedProduct.objects.filter(orders=bundle.obj)
替换为orders
并将 related_name='orders'
从资源移动到模型。
最后:
型号:
class OrderedProduct(models.Model):
products = models.ForeignKey(Products, on_delete=models.DO_NOTHING)
orders = models.ForeignKey(Orders, on_delete=models.CASCADE, related_name='orders')
quantity = models.IntegerField(default=0)
price = models.DecimalField(default=0.00, max_digits=5, decimal_places=2, blank=False)
资源:
class OrdersResource(ModelResource):
ordered_products = fields.ToManyField('orders.resources.OrderedProductResource',
'orders', full=True, null=True)
contact_no = fields.ForeignKey(ProductUsersResource, 'users')
address = fields.ForeignKey(ProductUsersAddressResource, 'address')
class Meta:
queryset = Orders.objects.all()
resource_name = 'orders'
include_resource_uri = False
collection_name = 'orders'
allowed_methods = ['get', 'post']
always_return_data = True
def hydrate_m2m(self, bundle):
for ordered_product in bundle.data['ordered_products']:
if isinstance(ordered_product, dict):
ordered_product.update({'orders': bundle.obj})
return super(OrdersResource, self).hydrate_m2m(bundle)
和POST数据:
{
"address": "/api/v1/address/1",
"contact_no": "/api/v1/users/8269661606",
"order_id": "ABCDE",
"ordered_products": [
{
"price": "40.00",
"products": "/api/v1/products/1",
"quantity": 2
},
{
"price": "70.00",
"products": "/api/v1/products/2",
"quantity": 4
},
{
"price": "67.00",
"products": "/api/v1/products/3",
"quantity": 7
}
],
"payment_method": "COD",
}
我的models.py
class Orders(models.Model):
order_id = models.CharField(max_length=7, primary_key=True)
users = models.ForeignKey(ProductUsers, on_delete=models.DO_NOTHING)
address = models.ForeignKey(ProductUsersAddress, on_delete=models.DO_NOTHING)
payment_method = models.CharField(default='COD', max_length=20, choices=PAYMENT_METHOD)
class OrderedProduct(models.Model):
products = models.ForeignKey(Products, on_delete=models.DO_NOTHING)
orders = models.ForeignKey(Orders, on_delete=models.CASCADE)
quantity = models.IntegerField(default=0)
price = models.DecimalField(default=0.00, max_digits=5, decimal_places=2, blank=False)
我的resources.py
class OrdersResource(ModelResource):
ordered_products = fields.ToManyField('orders.resources.OrderedProductResource',
attribute=lambda bundle: OrderedProduct.objects.filter(orders=bundle.obj),
related_name='orders', full=True, null=True)
contact_no = fields.ForeignKey(ProductUsersResource, 'users')
address = fields.ForeignKey(ProductUsersAddressResource, 'address')
class Meta:
queryset = Orders.objects.all()
resource_name = 'orders'
include_resource_uri = False
collection_name = 'orders'
allowed_methods = ['get', 'post']
always_return_data = True
class OrderedProductResource(ModelResource):
products = fields.ForeignKey(ProductsResource, 'products')
orders = fields.ForeignKey(OrdersResource, 'orders')
class Meta:
queryset = OrderedProduct.objects.all()
resource_name = 'ordered_products'
excludes = ['id']
include_resource_uri = False
我使用 Django-Admin 输入数据。
当我点击时,http://localhost:8000/orders/
,我得到,
{
"orders": [
{
"address": "/api/v1/address/1",
"contact_no": "/api/v1/users/8269661606",
"order_id": "KJLSWI",
"ordered_products": [
{
"orders": "/api/v1/orders/KJLSWI",
"price": "40.00",
"products": "/api/v1/products/1",
"quantity": 2
},
{
"orders": "/api/v1/orders/KJLSWI",
"price": "70.00",
"products": "/api/v1/products/2",
"quantity": 4
},
{
"orders": "/api/v1/orders/KJLSWI",
"price": "67.00",
"products": "/api/v1/products/3",
"quantity": 7
}
],
"payment_method": "COD",
}
]
}
现在根据 tasty 文档,
Tastypie encourages “round-trippable” data, which means the data you can GET should be able to be POST/PUT’d back to recreate the same object. If you’re ever in question about what you should send, do a GET on another object & see what Tastypie thinks it should look like.
但是当我 post 相同的数据只是改变主键时,
{
"address": "/api/v1/address/1",
"contact_no": "/api/v1/users/8269661606",
"order_id": "ABCDE",
"ordered_products": [
{
"orders": "/api/v1/orders/ABCDE",
"price": "40.00",
"products": "/api/v1/products/1",
"quantity": 2
},
{
"orders": "/api/v1/orders/ABCDE",
"price": "70.00",
"products": "/api/v1/products/2",
"quantity": 4
},
{
"orders": "/api/v1/orders/ABCDE",
"price": "67.00",
"products": "/api/v1/products/3",
"quantity": 7
}
],
"payment_method": "COD",
}
我收到回复,
{
"address": "/api/v1/address/1",
"contact_no": "/api/v1/users/8269661606",
"ordered_products": [],
"payment_method": "COD",
}
我在模型 OrderedProduct
中的数据没有保存。为什么 YYYYYY ??????
试试这个:
def hydrate_m2m(self, bundle):
for ordered_product in bundle.data['ordered_products']:
if isinstance(ordered_product, dict):
ordered_product.update({'orders': bundle.obj})
return super(OrdersResource, self).hydrate_m2m(bundle)
并从 ordered_products
JSON
orders
键
并将attribute=lambda bundle: OrderedProduct.objects.filter(orders=bundle.obj)
替换为orders
并将 related_name='orders'
从资源移动到模型。
最后:
型号:
class OrderedProduct(models.Model):
products = models.ForeignKey(Products, on_delete=models.DO_NOTHING)
orders = models.ForeignKey(Orders, on_delete=models.CASCADE, related_name='orders')
quantity = models.IntegerField(default=0)
price = models.DecimalField(default=0.00, max_digits=5, decimal_places=2, blank=False)
资源:
class OrdersResource(ModelResource):
ordered_products = fields.ToManyField('orders.resources.OrderedProductResource',
'orders', full=True, null=True)
contact_no = fields.ForeignKey(ProductUsersResource, 'users')
address = fields.ForeignKey(ProductUsersAddressResource, 'address')
class Meta:
queryset = Orders.objects.all()
resource_name = 'orders'
include_resource_uri = False
collection_name = 'orders'
allowed_methods = ['get', 'post']
always_return_data = True
def hydrate_m2m(self, bundle):
for ordered_product in bundle.data['ordered_products']:
if isinstance(ordered_product, dict):
ordered_product.update({'orders': bundle.obj})
return super(OrdersResource, self).hydrate_m2m(bundle)
和POST数据:
{
"address": "/api/v1/address/1",
"contact_no": "/api/v1/users/8269661606",
"order_id": "ABCDE",
"ordered_products": [
{
"price": "40.00",
"products": "/api/v1/products/1",
"quantity": 2
},
{
"price": "70.00",
"products": "/api/v1/products/2",
"quantity": 4
},
{
"price": "67.00",
"products": "/api/v1/products/3",
"quantity": 7
}
],
"payment_method": "COD",
}