2012-08-01 55 views
2

給定兩個有關Django模型一對多關係:發佈數據以同時創建相關的Tastypie資源?

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作爲外鍵?

如果有人能拿出一個帖子的例子(例如使用python字典和httplib2,或curl),這將是很好的。

非常感謝。

回答

1

這裏是一個解決方案,涉及多對多而不是一對多關係:

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的關係可能會有更好的解決方案嗎?

2

解決方法就在這裏。使用tastypie字段的相關名稱,可以在創建多個對象的同時自動填充反向關係。 http://django-tastypie.readthedocs.org/en/v0.10.0/fields.html#tastypie.fields.RelatedField.related_name

RelatedField.related_name

用於幫助自動創建數據時填充反向關係。默認爲None。

爲了使此選項正常工作,其他資源上必須有一個字段,並將其作爲屬性/ 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一樣,它會生成超出最大遞歸深度的異常,因爲兩個資源在其他資源中都是完整的。

相關問題