2

给定OneToMany关系中的两个相关 Django 模型AB :

模型.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 作为外键?

如果有人能想出一个帖子示例(例如使用 python 字典和 httplib2 或 curl),那就太好了。

太感谢了。

4

2 回答 2

2

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

RelatedField.related_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在资源的两侧所做的那样,它将产生超出最大递归深度的异常,因为这两个资源彼此都已满。

于 2013-11-13T07:42:38.530 回答
1

这是一种涉及多对多而不是单对多关系的解决方案:

模型.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 脚本发布数据的工作示例基于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关系可能有更好的解决方案?

于 2012-08-02T13:11:13.803 回答