Django Deliciouspie“ ToManyField”在“父母”中资源似乎破坏了POST的智利资源 [英] Django Tastypie "ToManyField" in "parent" resource seems to break POST to chile resource

查看:83
本文介绍了Django Deliciouspie“ ToManyField”在“父母”中资源似乎破坏了POST的智利资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Django 1.4.3和DeliciousPie 0.9.11。

I am using Django 1.4.3 and TastyPie 0.9.11.

我有以下两种django模型:

I have the following two django models:

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资源:

Then I have the following API Resources:

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关系,这也适用。

As you can see, I have set up a "ToManyField" relation ship in order to have Event Invitees to show up in GET lists of the Events resource. This works Correctly. Please note that there is also an FK relationship to a "store" and this also works.

在将以下内容发布到 EventInviteesResource以创建和EventInvitee时出现错误:

The error comes when POSTing the following to "EventInviteesResource" to create and EventInvitee:

POST http:// XXXX:8000 / api / v1 / eventinvitees /?username = user& api_key = XXXXXXX

{
  "event" : {"pk" : 30},
  "invitee" : 2,
  "confirmed" : true
}

返回的错误是:

被邀请者字段没有数据,不允许空值。

"The 'invitees' field has no data and doesn't allow a null value."

请注意, invitees在 EventInviteesResource中不存在,而在父资源 EventResource中存在。所以我不明白这怎么可能是一个错误。
如果我将这一行注释掉:

Note that "invitees" does NOT exist in the "EventInviteesResource" but instead in the "parent" resource "EventResource". So I dont understand how this can even be an error. If I comment out the this line:

invitees = fields.ToManyField('bbservices.api.EventInviteesResource', 'invitees', full=True)

资源 EventResource,被邀请者错误消失并且错误变为:

the resource "EventResource" the "invitees" error goes away and the error becomes:

{"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"}

如果我尝试POST this:

If I try to POST this:

{
    "store_id" : 1, 
    "name" : "With Invitees", 
    "event_time" : "2013-02-06T18:30-3:00",
    "requires_confirmation" : true,
    "invitees" : [
                    {
                      "invitee": {"pk" : 1}
                    }
                ]
}

到资源EventResource,被邀请者关系完好无损,错误是:

to the resource EventResource, with the 'invitees' relationship intact, the error is:

{"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"}

我相信这里记录了此错误:

I believe this error is documented here:

https://github.com / toastdriven / django-tastypie / issues / 307

如果我评论 invitees这一行并发布到EventResource,错误消失了,但是被邀请者当然是

If I comment the "invitees" line and POST to EventResource the error disappears but of course the invitees are not created.

所以……..任何人都有想法吗?这仅仅是与问题307(上面的链接)相关的另一个错误吗?还是我做错了什么?

So........any one have any ideas? Is this just another error associated with issue 307 (link above) or am I doing something wrong??

非常感谢!!!

推荐答案

好的,我找到了自己的答案。在EventInviteesResource

OK, I found my own answer. In EventInviteesResource

user = fields.ForeignKey(UserResource, 'invitee', full=True)

为了反映我的Django模型,需要满足以下条件:

Needs to be the following in order to mirror my Django Model:

invitee = fields.ForeignKey(UserResource, 'invitee', full=True)

虽然这看起来很合逻辑,但我必须说我收到的被邀请者(请注意 s)错误不是但哦...

While this DOES seem logical, I must say that the "invitees" (notice the "s") error I was getting does NOT but oh well...

奖励答案,在EventResource中,更新:

Bonus Answer, in EventResource, update:

invitees = fields.ToManyField('bbservices.api.EventInviteesResource', 'invitees', full=True)

收件人:

invitees = fields.ToManyField('bbservices.api.EventInviteesResource', 'invitees', related_name='event', full=True)

现在您可以与被邀请者一起发布到EventResource,并自动创建邀请者。发布数据如下所示:

An now you can post to EventResource with invitees and have those created automatically as well. The post data would look like this:

{
    "store" : "/api/v1/store/2/", 
    "name" : "Yes again?", 
    "event_time" : "2013-02-06T18:30-3:00",
    "requires_confirmation" : true,
    "invitees" : [
                    {
                      "invitee" : "/api/v1/user/1/",
                      "confirmed" : true
                    }
                ]
}

所以现在我唯一的疑问是……谁能告诉我为什么我不能对FK使用PK语法:

So now my only doubt is...can anyone tell me why I cant use the PK syntax for FKs:

{ "store" : {"pk" : 2}, ...

这会导致错误,指出Store对象的字段不能为null,就像试图创建一个新商店对象。如果我使用如下所示的URI路径,则可以正常工作:

This results in errors stating that fields for the Store object cannot be null as if it was try to create a new store object. If I use the URI path as below it works fine:

{ "store" : "/api/v1/store/2/", ...

但是我希望不必传递完整的URI,而我应该要。
这就是为什么我在obj_create中使用store_id技巧,但它非常笨拙...

But I would prefer not to have to pass back the full URI and I should have to. That is why I'm using the store_id trick in obj_create but its VERY kludgy...

任何想法吗?

这篇关于Django Deliciouspie“ ToManyField”在“父母”中资源似乎破坏了POST的智利资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆