您好我正在使用tastypie在项目中公开一个rest api,并且卡在如何实现资源的端点上,所以这是我的问题:
我有以下型号,
class Product(models.Model):
# fields...
class Order(models.Model):
products = models.ManyToManyField('Product', through='OrderProduct')
# other fields...
class OrderProduct(models.Model):
order = models.ForeignKey('Order')
product = models.ForeignKey('Product')
quantity = models.IntegerField()
unit_price = models.FloatField()
class Meta:
unique_together = ['order', 'product']
以及以下资源
class ProductResource(ModelResource):
class Meta:
resource_name = 'products'
queryset = Product.objects.all()
allowed_methods = ['get']
class OrderResource(ModelResource):
products = fields.ToManyField('agro.api.OrderProductResource', 'orderproduct_set', related_name='product', full=True)
class Meta:
resource_name = 'orders'
queryset = Order.objects.all()
list_allowed_methods = ['get', 'post']
detail_allowed_methods = ['get', 'put', 'delete']
authentication = Authentication() # only for testing purposes
authorization = Authorization() # only for testing purposes
class OrderProductResource(ModelResource):
product = fields.ForeignKey('agro.api.ProductResource', 'product')
class Meta:
resource_name = 'orderproducts'
queryset = OrderProduct.objects.all()
allowed_methods = ['get']
include_resource_uri = False
authentication = Authentication() # only for testing purposes
authorization = Authorization() # only for testing purposes
当我尝试使用以下请求数据POST到/ orders / endpoint时
{
"products": [
{
"product": "/products/1/",
"quantity": 4,
"unit_price": 5
}
]
}
我收到以下错误追溯
{
"error_message": "orderproduct.order_id may not be NULL",
"traceback": "Traceback (most recent call last):\n\n File \"c:\\Python27\\lib\\site-packages\\tastypie\\resources.py\", line 192, in wrapper\n response = callback(request, *args, **kwargs)\n\n File \"c:\\Python27\\lib\\site-packages\\tastypie\\resources.py\", line 397, in dispatch_list\n return self.dispatch('list', request, **kwargs)\n\n File \"c:\\Python27\\lib\\site-packages\\tastypie\\resources.py\", line 427, in dispatch\n response = method(request, **kwargs)\n\n File \"c:\\Python27\\lib\\site-packages\\tastypie\\resources.py\", line 1165, in post_list\n updated_bundle = self.obj_create(bundle, request=request, **self.remove_api_resource_names(kwargs))\n\n File \"c:\\Python27\\lib\\site-packages\\tastypie\\resources.py\", line 1784, in obj_create\n self.save_m2m(m2m_bundle)\n\n File \"c:\\Python27\\lib\\site-packages\\tastypie\\resources.py\", line 1951, in save_m2m\n related_bundle.obj.save()\n\n File \"c:\\Python27\\lib\\site-packages\\django\\db\\models\\base.py\", line 463, in save\n self.save_base(using=using, force_insert=force_insert, force_update=force_update)\n\n File \"c:\\Python27\\lib\\site-packages\\django\\db\\models\\base.py\", line 551, in save_base\n result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw)\n\n File \"c:\\Python27\\lib\\site-packages\\django\\db\\models\\manager.py\", line 203, in _insert\n return insert_query(self.model, objs, fields, **kwargs)\n\n File \"c:\\Python27\\lib\\site-packages\\django\\db\\models\\query.py\", line 1593, in insert_query\n return query.get_compiler(using=using).execute_sql(return_id)\n\n File \"c:\\Python27\\lib\\site-packages\\django\\db\\models\\sql\\compiler.py\", line 912, in execute_sql\n cursor.execute(sql, params)\n\n File \"c:\\Python27\\lib\\site-packages\\django\\db\\backends\\util.py\", line 40, in execute\n return self.cursor.execute(sql, params)\n\n File \"c:\\Python27\\lib\\site-packages\\django\\db\\backends\\sqlite3\\base.py\", line 344, in execute\n return Database.Cursor.execute(self, query, params)\n\nIntegrityError: orderproduct.order_id may not be NULL\n"
}
正如您所看到的,我没有指定新OrderProduct应该与之相关的订单,我想要实现的是发布Order资源,其中嵌套的OrderProduct数据是在同一个POST请求中创建的。
我的问题是如何指定OrderProduct引用的Order应该是当前正在创建的订单,什么是最惯用的方法,覆盖水合物(不确定此时我是否有django orm order对象实例并因此可以设置相关模型的顺序或重新实现hydrate_m2m甚至save_m2m,任何关于如何做的消息?
答案 0 :(得分:0)
感谢您的回答,我确实缺少订单但在我的情况下必须是这样的方式,这个数据表示要创建的订单以及填充中间表OrderProduct(json产品字段)的相关数据,所以这个想法是关于订单的api传递信息的用户以及关于相同请求的相关数据,例如要创建新订单,用户将使用以下数据进行POST
{
"products": {
"product": "/products/1",
"quantity": 4,
"unit_price": 5
}
}
这些数据应生成以下数据库寄存器
Order
# with and auto generated id
OrderProduct
order # which points to the auto generated id
product # points to a previous registered product
如果我通过了订单字段,此时我没有任何有效的ID(鸡蛋问题的种类),因为订单尚未保存在数据库中,tastypie数据流将保存订单在ModelResource上。 obj_save方法和该方法将调用ModelResource.save_m2m,它创建发生异常的OrderProduct寄存器。
所以我需要知道我必须实现哪个tastypie钩子才能在save_m2m尝试保存OrderProduct之前隐式设置该引用。