我使用Django 1.4.3和TastyPie 0.9.11。
我有以下两个Django模型:
class Event(models.Model):
organizer = models.ForeignKey(User, related_name='Organizador')
store = models.ForeignKey(Store, related_name='Tienda')
name = models.CharField('Titulo', max_length=50)
event_time = models.DateTimeField('Fecha y Hora del Evento')
creation_date = models.DateTimeField('Fecha de Creación', auto_now_add=True)
requires_confirmation = models.BooleanField('Require Confirmación')
class Meta:
verbose_name = "Encuentro"
verbose_name_plural = "Encuentros"
class EventInvitees(models.Model):
event = models.ForeignKey(Event, related_name='invitees')
invitee = models.ForeignKey(User, verbose_name='Invitado')
confirmed = models.BooleanField('Confirmado')
confirmation_date = models.DateTimeField('Fecha de Confirmación', null=True, auto_now=True)
class Meta:
verbose_name = "Invitados"
verbose_name_plural = "Invitados"
然后,我有以下的API资源:
class EventInviteesResource(ModelResource):
user = fields.ForeignKey(UserResource, 'invitee', full=True)
event = fields.ForeignKey('bbservices.api.EventResource', 'event')
class Meta:
queryset = EventInvitees.objects.all()
authentication = ApiKeyAuthentication()
authorization = Authorization()
class EventResource(ModelResource):
invitees = fields.ToManyField('bbservices.api.EventInviteesResource', 'invitees', full=True)
store = fields.ForeignKey(StoreResource, 'store', full=True)
class Meta:
#default_format = 'application/json'
queryset = Event.objects.all()
fields = ['organizer_id', 'store', 'name', 'event_time', 'requires_confirmation']
include_resource_uri = False
#list_allowed_methods = ['get', 'post']
authentication = ApiKeyAuthentication()
authorization = Authorization()
filtering = {
#'user': ALL_WITH_RELATIONS
'event_time': ['exact', 'range', 'gt', 'gte', 'lt', 'lte'],
}
def dehydrate_event_time(self, bundle):
return bundle.data['event_time']
def obj_create(self, bundle, request=None, **kwargs):
return super(EventResource, self).obj_create(bundle, request, organizer_id=request.user.pk, store_id=bundle.data['store_id'])
正如你所看到的,我已经为了有活动受邀者的活动资源的GET列表展现出来成立“ToManyField”关系船。 这正常工作。 请注意,也有一个“商店”的FK关系,这也适用。
张贴以下为“EventInviteesResource”创建和EventInvitee当错误出现:
POST HTTP:// XXXX:8000 / API / V1 / eventinvitees /用户名=用户API_KEY = XXXXXXX
{
"event" : {"pk" : 30},
"invitee" : 2,
"confirmed" : true
}
返回的错误是:
“在‘受邀者’字段没有数据,并且不允许空值。”
需要注意的是“被邀请者”不会在“EventInviteesResource”,但存在代替“父”资源“EventResource”。 所以,我不明白这甚至可以是一个错误。 如果我注释掉这一行:
invitees = fields.ToManyField('bbservices.api.EventInviteesResource', 'invitees', full=True)
资源“EventResource”中的“被邀请者”错误消失和错误变为:
{"error_message": "", "traceback": "Traceback (most recent call last):\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 192, in wrapper\n response = callback(request, *args, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 397, in dispatch_list\n return self.dispatch('list', request, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 427, in dispatch\n response = method(request, **kwargs)\n\n File \"/Library/Python/2.7/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 \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 1774, in obj_create\n bundle = self.full_hydrate(bundle)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 698, in full_hydrate\n value = field_object.hydrate(bundle)\n\n File \"/Library/Python/2.7/site-packages/tastypie/fields.py\", line 636, in hydrate\n value = super(ToOneField, self).hydrate(bundle)\n\n File \"/Library/Python/2.7/site-packages/tastypie/fields.py\", line 154, in hydrate\n elif self.attribute and getattr(bundle.obj, self.attribute, None):\n\n File \"/Library/Python/2.7/site-packages/django/db/models/fields/related.py\", line 343, in __get__\n raise self.field.rel.to.DoesNotExist\n\nDoesNotExist\n"}
如果我尝试发布此:
{
"store_id" : 1,
"name" : "With Invitees",
"event_time" : "2013-02-06T18:30-3:00",
"requires_confirmation" : true,
"invitees" : [
{
"invitee": {"pk" : 1}
}
]
}
到资源EventResource,与“受邀者”关系不变,错误的是:
{"error_message": "int() argument must be a string or a number, not 'dict'", "traceback": "Traceback (most recent call last):\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 192, in wrapper\n response = callback(request, *args, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 397, in dispatch_list\n return self.dispatch('list', request, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 427, in dispatch\n response = method(request, **kwargs)\n\n File \"/Library/Python/2.7/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 \"/Users/jleidigh/Documents/Starbucks - In Office/trunk/backend/bbservices/api.py\", line 234, in obj_create\n return super(EventResource, self).obj_create(bundle, request, organizer_id=request.user.pk, store_id=bundle.data['store_id'])\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 1783, in obj_create\n m2m_bundle = self.hydrate_m2m(bundle)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 743, in hydrate_m2m\n bundle.data[field_name] = field_object.hydrate_m2m(bundle)\n\n File \"/Library/Python/2.7/site-packages/tastypie/fields.py\", line 742, in hydrate_m2m\n m2m_hydrated.append(self.build_related_resource(value, **kwargs))\n\n File \"/Library/Python/2.7/site-packages/tastypie/fields.py\", line 593, in build_related_resource\n return self.resource_from_data(self.fk_resource, value, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/tastypie/fields.py\", line 548, in resource_from_data\n return fk_resource.obj_update(fk_bundle, **data)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 1814, in obj_update\n bundle.obj = self.obj_get(request, **lookup_kwargs)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 1752, in obj_get\n base_object_list = self.get_object_list(request).filter(**kwargs)\n\n File \"/Library/Python/2.7/site-packages/django/db/models/query.py\", line 624, in filter\n return self._filter_or_exclude(False, *args, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/django/db/models/query.py\", line 642, in _filter_or_exclude\n clone.query.add_q(Q(*args, **kwargs))\n\n File \"/Library/Python/2.7/site-packages/django/db/models/sql/query.py\", line 1250, in add_q\n can_reuse=used_aliases, force_having=force_having)\n\n File \"/Library/Python/2.7/site-packages/django/db/models/sql/query.py\", line 1185, in add_filter\n connector)\n\n File \"/Library/Python/2.7/site-packages/django/db/models/sql/where.py\", line 69, in add\n value = obj.prepare(lookup_type, value)\n\n File \"/Library/Python/2.7/site-packages/django/db/models/sql/where.py\", line 320, in prepare\n return self.field.get_prep_lookup(lookup_type, value)\n\n File \"/Library/Python/2.7/site-packages/django/db/models/fields/related.py\", line 137, in get_prep_lookup\n return self._pk_trace(value, 'get_prep_lookup', lookup_type)\n\n File \"/Library/Python/2.7/site-packages/django/db/models/fields/related.py\", line 210, in _pk_trace\n v = getattr(field, prep_func)(lookup_type, v, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/django/db/models/fields/__init__.py\", line 310, in get_prep_lookup\n return self.get_prep_value(value)\n\n File \"/Library/Python/2.7/site-packages/django/db/models/fields/__init__.py\", line 537, in get_prep_value\n return int(value)\n\nTypeError: int() argument must be a string or a number, not 'dict'\n"}
我相信这个错误记录在这里:
https://github.com/toastdriven/django-tastypie/issues/307
如果我评论了“被邀请者”线和POST到EventResource错误消失,但当然不会创建被邀请者。
所以........任何一个有什么想法? 与问题307(以上链接)相关联。这只是一个错误还是我做错了什么?
首先十分感谢!!!!