Я использую backbone-tastypie для создания вложенного ресурса.
class ServiceResource(ModelResource):
manager = fields.ToOneField(UserResource, 'manager',full=True)
area = fields.ToOneField(AreaResource, 'area',full=True)
specification = fields.ToManyField('services.api.ServiceSpecResource','servicespec_set',full=True)
class Meta:
queryset = Service.objects.all()
resource_name = 'service'
class ServiceSpecResource(ModelResource):
service = fields.ToOneField(ServiceResource,'service')
servicespecrange = fields.ToManyField('services.api.ServiceSpecRangeResource','servicespecrange_set',full=True)
servicespecconstant = fields.ToManyField('services.api.ServiceSpecConstantResource','servicespecconstant_set',full=True)
servicespecgeneric = fields.ToManyField('services.api.ServiceSpecGenericResource','servicespecgeneric_set',full=True)
class Meta:
queryset = ServiceSpec.objects.all()
resource_name = 'servicespec'
list_allowed_methods = ['get', 'post']
detail_allowed_methods = ['get', 'put', 'delete']
authorization = DjangoAuthorization()
class ServiceSpecRangeResource(ModelResource):
servicespec = fields.ToOneField(ServiceSpecResource,'service_spec')
class Meta:
queryset = ServiceSpecRange.objects.all()
resource_name = 'servicespecrange'
class ServiceSpecConstantResource(ModelResource):
servicespec = fields.ToOneField(ServiceSpecResource,'service_spec')
class Meta:
queryset = ServiceSpecConstant.objects.all()
resource_name = 'servicespecconstant'
class ServiceSpecGenericResource(ModelResource):
servicespec = fields.ToOneField(ServiceSpecResource,'service_spec')
class Meta:
queryset = ServiceSpecGeneric.objects.all()
resource_name = 'servicespecgeneric'
Для получения ServiceResource он отлично работает. Я возвращаю объект службы, который содержит все ServiceSpecification, который, в свою очередь, имеет все ServiceSpecRange/константы и т. д.
Возврат всего вложенного ресурса обратно на сервер также отлично работает для существующих данных.
Однако всякий раз, когда я пытаюсь опубликовать весь вложенный ресурс за один раз (новый сервис с прикрепленным новым сервисом), я получаю:
Аргумент int() должен быть строкой или числом, а не списком.
У меня была эта ошибка раньше, и я обнаружил, что она связана с отсутствием включения resource_uri в связанный ресурс. Но в этом случае я публикую, поэтому не следует жаловаться на отсутствие resource_uri во вложенном ресурсе. Причина, по которой они не включены, заключается в том, что родительский ресурс еще не сохранен. Вкусный пирог недостаточно продвинут, чтобы увидеть это?
Вот трассировка:
{ "error_message":"Аргумент int() должен быть строкой или числом, а не 'списком'", "traceback":"Traceback (самый последний вызов последним):
Файл \"build/bdist.linux-x86_64/egg/tastypie/resources.py\", строка 192, в обертке response = callback(request, *args, **kwargs)
F> файл \"build/bdist.linux-x86_64/egg/tastypie/resources.py\", строка 397, в dispatch_list return self.dispatch('list', request, **kwargs)
Файл \"build/bdist.linux-x86_64/egg/tastypie/resources.py\", строка 427, в ответе отправки = метод (запрос, **kwargs)
Файл \"build/bdist.linux-x86_64/egg/tastypie/resources.py\", строка 1165, в post_list updated_bundle = self.obj_create(bundle, request=request, **self.remove_api_resource_names(kwargs))
Файл \"build/bdist.linux-x86_64/egg/tastypie/resources.py\", строка 1783, в obj_create m2m_bundle = self.hydra_m2m(bundle)
Файл \"build/bdist.linux-x86_64/egg/tastypie/resources.py\", строка 743, в hydrate_m2m bundle.data[field_name] = field_object.hydr_m2m(bundle)
Файл \"build/bdist.linux-x86_64/egg/tastypie/fields.py\", строка 742, в hydrate_m2m m2m_hydrated.append(self.build_related_resource(value, **kwargs))
Файл \"build/bdist.linux-x86_64/egg/tastypie/fields.py\", строка 593, в build_related_resource возвращает self.resource_from_data(self.fk_resource, значение, **kwargs)
Файл \"build/bdist.linux-x86_64/egg/tastypie/fields.py\", строка 548, в resource_from_data возвращает fk_resource.obj_update(fk_bundle, **data)
Файл \"build/bdist.linux-x86_64/egg/tastypie/resources.py\", строка 1814, в obj_update bundle.obj = self.obj_get(request, **lookup_kwargs)
Файл \"build/bdist.linux-x86_64/egg/tastypie/resources.py\", строка 1752, в obj_get base_object_list = self.get_object_list(request).filter(**kwargs)
Файл \"/usr/local/lib/python2.7/site-packages/django/db/models/query.py\", строка 550, в фильтре return self._filter_or_exclude(False, *args, **kwargs)
Файл \"/usr/local/lib/python2.7/site-packages/django/db/models/query.py\", строка 568, в _filter_or_exclude clone.query.add_q(Q(*args, **kwargs) )
Файл \"/usr/local/lib/python2.7/site-packages/django/db/models/sql/query.py\", строка 1194, в add_q can_reuse=used_aliases, force_having=force_having)
Файл \"/usr/local/lib/python2.7/site-packages/django/db/models/sql/query.py\", строка 1129, в коннекторе add_filter)
Файл \"/usr/local/lib/python2.7/site-packages/django/db/models/sql/where.py\", строка 67, в add value = obj.prepare(lookup_type, value)
Файл \"/usr/local/lib/python2.7/site-packages/django/db/models/sql/where.py\", строка 316, при подготовке return self.field.get_prep_lookup(lookup_type, value)
Файл \"/usr/local/lib/python2.7/site-packages/django/db/models/fields/related.py\", строка 136, в get_prep_lookup возвращает self._pk_trace(value, 'get_prep_lookup', lookup_type)
Файл \"/usr/local/lib/python2.7/site-packages/django/db/models/fields/related.py\", строка 209, в _pk_trace v = getattr(field, prep_func)(lookup_type, v, **кваргс)
Файл \"/usr/local/lib/python2.7/site-packages/django/db/models/fields/init.py\", строка 292, в get_prep_lookup return self.get_prep_value(value )
Файл \"/usr/local/lib/python2.7/site-packages/django/db/models/fields/init.py\", строка 479, в get_prep_value возвращает int(value)
TypeError: аргумент int() должен быть строкой или числом, а не списком " }
ИЗМЕНИТЬ:
Я считаю, что эта проблема связана:
https://github.com/toastdriven/django-tastypie/issues/307
Наряду с этим тестовым случаем:
https://github.com/joshbohde/django-tastypie/commit/eef8d27fb65d5777a94a36df033