【问题标题】:Create Object with OneToOneField in django tastypie在 django sweetpie 中使用 OneToOneField 创建对象
【发布时间】:2012-08-01 09:12:04
【问题描述】:

我有两个模型: Project 和 Album 。它们通过 oneToOneField 相互关联。

专辑/models.py:

class Album(models.Model):
    title = models.CharField(_('title'), max_length=128)
    slug = models.SlugField(_('slug'), unique=True, default='main-gallery')

项目/models.py

class Project(models.Model):
    title = models.CharField(_('title'), max_length=300)
    slug = models.SlugField(_('slug'), unique=True)

    main_gallery = models.OneToOneField(Album, verbose_name=_('related main album'), related_name='project', unique=True)

@receiver(pre_save, sender=Project)
def create_project(sender, instance=None, **kwargs):
    if instance is None:
    try:
        str(instance.main_gallery)
    except Album.DoesNotExist:
        main_gallery = Album.objects.create(title=''.join((instance.title, ' - ', 'main gallery')))

如果创建了一个项目,也会为其创建一个专辑。这工作正常。但是当我尝试使用 django sweetpie 在我的 api 中创建一个时它不会起作用:

class AlbumResource(ModelResource):
    class Meta:
        queryset = Album.objects.all()
        resource_name = 'album'
        #fields = ['title','slug',]

    def dehydrate_resource_uri(self, bundle):
        return bundle.data['slug']

class ProjectResource(ModelResource):
    main_gallery = fields.OneToOneField(AlbumResource, 'main_gallery', related_name='project', full=False)
    class Meta:
        queryset = Project.objects.all()
        resource_name = 'project'
        fields = ['slug', 'title', 'main_gallery']

        authorization= Authorization()

        allowed_methods = ['get', 'post', 'put']

def obj_create(self, bundle, request=None, **kwargs):
    logger.debug("obj_create Bundle %s" % bundle)
    return super(ProjectResource, self).obj_create(bundle, request, created_by=request.user)

虽然Project API 端点上的“GET”有效,但当我尝试通过“POST”创建新的Project 时,我收到以下错误:

    Traceback (most recent call last):
  File "/Users/PATHvenv/lib/python2.7/site-packages/django/core/handlers/base.py", line 111, in get_response
    response = callback(request, *callback_args, **callback_kwargs)
  File "/Users/PATHvenv/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 77, in wrapped_view
    return view_func(*args, **kwargs)
  File "/Users/PATHvenv/lib/python2.7/site-packages/tastypie/resources.py", line 192, in wrapper
    response = callback(request, *args, **kwargs)
  File "/Users/PATHvenv/lib/python2.7/site-packages/tastypie/resources.py", line 397, in dispatch_list
    return self.dispatch('list', request, **kwargs)
  File "/Users/PATHvenv/lib/python2.7/site-packages/tastypie/resources.py", line 427, in dispatch
    response = method(request, **kwargs)
  File "/Users/PATHvenv/lib/python2.7/site-packages/tastypie/resources.py", line 1165, in post_list
    updated_bundle = self.obj_create(bundle, request=request, **self.remove_api_resource_names(kwargs))
  File "/Users/PATH/path/path/apps/api/resources.py", line 70, in obj_create
    return super(ProjectResource, self).obj_create(bundle, request, created_by=request.user)
  File "/Users/PATHvenv/lib/python2.7/site-packages/tastypie/resources.py", line 1774, in obj_create
    bundle = self.full_hydrate(bundle)
  File "/Users/PATHvenv/lib/python2.7/site-packages/tastypie/resources.py", line 698, in full_hydrate
    value = field_object.hydrate(bundle)
  File "/Users/PATHvenv/lib/python2.7/site-packages/tastypie/fields.py", line 636, in hydrate
    value = super(ToOneField, self).hydrate(bundle)
  File "/Users/PATHvenv/lib/python2.7/site-packages/tastypie/fields.py", line 154, in hydrate
    elif self.attribute and getattr(bundle.obj, self.attribute, None):
  File "/Users/PATHvenv/lib/python2.7/site-packages/django/db/models/fields/related.py", line 343, in __get__
    raise self.field.rel.to.DoesNotExist
DoesNotExist

【问题讨论】:

  • 如果您找到了解决方案,请考虑发布。

标签: python django tastypie


【解决方案1】:

原因是 Tastypie 在到达您的pre_save 接收器之前失败了。根据您粘贴的回溯,它在full_hydrate 中失败。这样做的原因是默认情况下main_gallery 是必需的,而不是给出(因为您假设它将被创建)。

尝试将blank=True, null=True 添加到

main_gallery = fields.OneToOneField(AlbumResource, 'main_gallery', related_name='project', full=False)

【讨论】:

  • 有推荐的地方可以抓到这个DoesNotExist吗?或者在它达到 full_hydrate 之前在某个地方把它捡起来?
  • 好的,但是如果需要关系怎么办,那么blank=True, null=True 没有意义?
  • @mrmagooey 你可以在调用链中的任何地方捕获它,例如在obj_create,但它不会做任何有用的事情。因为问题更根本。它试图水合关系,但请求没有指定使用哪个对象。这应该在表单中处理,但直到 save 才会调用表单,这发生在 hydrate 之后。
猜你喜欢
  • 2020-07-15
  • 2021-09-21
  • 1970-01-01
  • 2015-01-02
  • 1970-01-01
  • 2014-05-11
  • 2016-07-22
  • 2020-10-10
  • 1970-01-01
相关资源
最近更新 更多