當我創建與外國關係的新資源,指定爲,即{"pk": 20}
,我得到創建了一個新的不必要的FK-項目。tastypie - 禁用嵌套的對象創建
我有Order
模型類與Language
模型的關係,所以當創建一個Order實例時,我可能必須指定訂單的語言。語言列表應該是恆定的,並且用戶不能有修改存在或創建新語言的能力。
Order
資源:
class OrderResource(ModelResource):
user = fields.ForeignKey(UserResource, 'user', null=True, full=True)
src_lang = fields.ForeignKey(LanguageResource, 'src_lang', null=True, full=True)
dst_lang = fields.ForeignKey(LanguageResource, 'dst_lang', null=True, full=True)
def obj_create(self, bundle, request=None, **kwargs):
return super(OrderResource, self).obj_create(bundle, request, user=request.user)
class Meta:
resource_name = 'orders'
queryset = Order.objects.all()
serializer = Serializer(['json'])
authentication = MultiAuthentication(SessionAuthentication(), ApiKeyAuthentication())
authorization = ResourceAuthorization()
這裏是一個Language
資源:
class Language(models.Model):
name = models.CharField(max_length=100)
code = models.CharField(max_length=100)
class LanguageResource(ModelResource):
class Meta:
resource_name = 'languages'
queryset = Language.objects.all()
allowed_methods = ['get']
authorization = ReadOnlyAuthorization()
serializer = Serializer(['json'])
我試圖創建一個新的Order
使用jQuery:
var data = JSON.stringify({
"comment": "Something random",
"src_lang": {"pk": "20"},
"dst_lang": "/api/v2/languages/72/"
});
$.ajax({
type: 'POST',
url: '/api/v2/orders/',
data: data,
dataType: "json",
contentType: "application/json"
});
而不是設置pk:20
至src_lang_id
d,它會創建一個新的Language
與src_lang
空字段,併爲dst_lang
正確的值。但空的字段受限於Language
模型定義。它如何保存它?
還因爲我已經直線指定語言模型只讀訪問,只get
用於訪問支持的語言列表方法是自嘆不如。
如果我將OrderResource
類的語言字段聲明爲src_lang = fields.ForeignKey(LanguageResource, 'src_lang', null=True, full=True, readonly=True)
,它不會創建任何內容,但也不會爲外鍵設置任何值。
所以,我只需要指定一個existant語言,我不需要創建它。
UPDATE
ResourceAuthorization
:
class ResourceAuthorization(Authorization):
def is_authorized(self, request, object=None):
user = getattr(request, 'user', None)
if not user:
return False
return user.is_authenticated()
def apply_limits(self, request, object_list):
if request and hasattr(request, 'user'):
if request.user.is_superuser:
return object_list
return object_list.filter(user=request.user)
return object_list.none()
更新2
我什麼也沒找到更聰明的決策領域只讀和壓倒一切的obj_create
方法:
class OrderResource(ModelResource):
user = fields.ForeignKey(UserResource, 'user', null=True, full=True)
src_lang = fields.ForeignKey(LanguageResource, 'src_lang', null=True, full=True, blank=True, readonly=True)
dst_lang = fields.ForeignKey(LanguageResource, 'dst_lang', null=True, full=True, blank=True, readonly=True)
def obj_create(self, bundle, request=None, **kwargs):
src_lang_id, dst_lang_id = bundle.data.get('src_lang', None), bundle.data.get('dst_lang', None)
if not all([src_lang_id, dst_lang_id]):
raise BadRequest('You should specify both source and destination language codes')
src_lang, dst_lang = Language.objects.guess(src_lang_id), Language.objects.guess(dst_lang_id)
if not all([src_lang, dst_lang]):
raise BadRequest('You should specify both source and destination language codes')
return super(OrderResource, self).obj_create(
bundle, request, user=request.user, src_lang=src_lang, dst_lang=dst_lang
)
class Meta:
resource_name = 'orders'
queryset = Order.objects.all()
serializer = Serializer(['json'])
authentication = MultiAuthentication(SessionAuthentication(), ApiKeyAuthentication())
authorization = ResourceAuthorization()
我看到它應該指定的格式,我不明白爲什麼它會創建一個新的'Language'實例。如果我將使用'/ api/v2/languages/20 /'作爲src_lang,它就可以正常工作。 'ResourceAuthorization'是[每用戶授權](http://django-tastypie.readthedocs.org/en/latest/cookbook.html#creating-per-user-resources) –
我現在看到ResourceAuthorization,但我是不確定其正確性。 –