发布数据以同时创建相关的Tastypie资源?

时间:2012-08-01 14:01:31

标签: django post foreign-keys nested tastypie

OneToMany 关系中给出两个相关的Django模型 A B

models.py

class A(models.Model):
  name = models.CharField(max_length=5)

class B(models.Model):
  name = models.CharField(max_length=5)
  a = models.ForeignKey(A)

给予(可能是非最佳的)Tastypie资源:

api.py

class AResource(ModelResource):
    bs = fields.ToManyField( 'projectname.api.BResource', 'bs', full = True)
    class Meta:
        queryset = A.objects.all()

class BResource(ModelResource):
    a = fields.ToOneField( AResource, 'a', full = True)
    class Meta:
        queryset = B.objects.all()

我们假设到目前为止数据库是空的。现在我有相关的外部数据,并希望用A的实例和B的几个实例来挤占数据库。

解决这个问题的最漂亮的Tastypionic方法是什么?是否有可能同时挤满A和B?或者我是否需要先挤出A,然后将B提供A的ID作为ForeignKey?

如果有人可以提出一个帖子示例(使用例如python词典和httplib2,或curl),那将会很棒。

万分感谢。

2 个答案:

答案 0 :(得分:2)

解决方案就在这里。使用tastypie字段的相关名称可以在一次创建多个对象时自动填充反向关系。 http://django-tastypie.readthedocs.org/en/v0.10.0/fields.html#tastypie.fields.RelatedField.related_name

RelatedField.related_name

用于帮助在创建数据时自动填充反向关系。默认为无。

为了使此选项正常工作,其他资源上必须有一个字段,并将其作为属性/ instance_name。通常这只是意味着添加一个反射的ToOneField指向后面。

示例:

class EntryResource(ModelResource):
    authors = fields.ToManyField('path.to.api.resources.AuthorResource', 'author_set', related_name='entry')

    class Meta:
        queryset = Entry.objects.all()
        resource_name = 'entry'

class AuthorResource(ModelResource):
    entry = fields.ToOneField(EntryResource, 'entry')

    class Meta:
        queryset = Author.objects.all()
        resource_name = 'author'

使用related_name执行任务。它映射相关字段的对象,并在创建数据时自动填充关系。

正如您在资源的两侧执行full=True一样,它将生成超出异常的最大递归深度,因为两个资源都相互充满。

答案 1 :(得分:1)

以下是一个涉及 ManyToMany 而非 OneToMany 关系的解决方案:

<强> models.py

class B(models.Model):
    name = models.CharField(max_length=5)

class A(models.Model):
    name = models.CharField(max_length=5)
    bs = models.ManyToManyField(B)

<强> api.py

class BResource(ModelResource):
    class Meta:
        queryset = B.objects.all()
        resource_name = 'b'

class AResource(ModelResource):
    bs = fields.ToManyField( BResource, 'bs', related_name = 'a', full = True, null=True)
    class Meta:
        queryset = A.objects.all()
        resource_name = 'a'

<强>卷曲

curl -v -H "Content-Type: application/json" -X POST --data '{"name":"a_name1", "bs":[{"name":"b_name1"}, {"name": "b_name2"}]}' http:<my_path>/api/a/

<强> httplib2.py

使用httplib2包通过python脚本发布数据的工作示例基于a neat and simple solution posted by warren-runk

post_dict(
    url='http:<my_path>/api/a/',
    dictionary={
        'name' : 'a_name1',
        'bs' : [
            {'name' : 'b_name1'},
            {'name' : 'b_name1'},
        ]
    }
)

但是,现在在数据库中创建了一个与A和B相关的附加表。可能有更好的解决方案基于A和B的 OneToMany 关系?