关于本站
1、基于Django+Bootstrap开发
2、主要发表本人的技术原创博客
3、本站于 2015-12-01 开始建站
接着上一篇初步使用tastypie的体悟,继续写体悟。这次主要聊聊tastypie对应model与model之间的关系。
tastypie既然可以通过ModelResource快速创建和Model对应的Resource。而Model和Model之间有时候会通过外键建立关系。我们获取对于的Resource时也需要显示对应有关系的Resource数据。这个在构建ModelResource时创建。例如有如下两个Model:
#coding:utf-8 from django.db import models class Author(models.Model): author_name = models.CharField(max_length=50) class Book(models.Model): book_name = models.CharField(max_length=50) authors = models.ManyToManyField(Author)
上面例子中有两个Model:Author(作者)和Book(书籍)。一本书可能有多个作者完成,而一个作者可能写多本书。这种关系是典型的多对多。若创建对应的ModelResource,代码如下:
#coding:utf-8 from .models import Author, Book from tastypie.resources import ModelResource class AuthorResource(ModelResource): class Meta: resource_name = 'author' queryset = Author.objects.all() allowed_methods = ['get'] class BookResource(ModelResource): class Meta: resource_name = 'book' queryset = Book.objects.all() allowed_methods = ['get']
但这么构建Resource的话,就无法在获取Book同时获取Author或获取Author同时获取Book。
需要再添加字段信息,例如在BookResource添加ToMany字段:
#coding:utf-8 from .models import Author, Book from tastypie.resources import ModelResource from tastypie import fields class AuthorResource(ModelResource): class Meta: resource_name = 'author' queryset = Author.objects.all() allowed_methods = ['get'] class BookResource(ModelResource): authors = fields.ToManyField(AuthorResource, 'authors') class Meta: resource_name = 'book' queryset = Book.objects.all() allowed_methods = ['get']
如果获取BookResource列表,objects中将得到如下一组数据:
[ { 'id':1, 'authors':['/api/v1/author/1','/api/v1/author/2'], 'book_name':'test_book1' }, { 'id':2, 'authors':['/api/v1/author/2'], 'book_name':'test_book2' } ]
这里的authors显示对应作者的明细链接,若需要显示全部信息的话还需要设置ToManyField属性:
class BookResource(ModelResource): authors = fields.ToManyField(AuthorResource, 'authors', full=True) class Meta: resource_name = 'book' queryset = Book.objects.all() allowed_methods = ['get']
再次获取列表数据,将得到完整的作者信息:
[ { 'id':1, 'authors':[{'id':1, 'author_name':'Bill'},{'id':2, 'author_name':'Lily'}], 'book_name':'test_book1' }, { 'id':2, 'authors':[{'id':1, 'author_name':'Bill'}], 'book_name':'test_book2' } ]
full参数是设置是否展开对应全部信息。有时我们不需要在获取列表是显示全部,只需要在获取明细时显示全部,可以设置full_detail=True;反之,若要只在列表数据显示全部,可以设置full_list=True。
BookResource设置关系没问题了,但AuthorResource没有设置外键关联到BookResource。若AuthorResource也使用同样的方式设置外键,会有解析错误的问题。因为解析到AuthorResource时,还没有加入BookResource。面对这种情况,可以采用如下的设置方式:
class AuthorResource(ModelResource): books = fields.ToManyField('path.to.api.resources.BookResource', 'book_set') class Meta: resource_name = 'author' queryset = Author.objects.all() allowed_methods = ['get']
ToManyField第1个参数使用字符串。该字符串写BookResource的引用路径。tastypie在使用该AuthorResource时才解析字符串指向的位置,避免解析错误。这是一种懒加载的方式。
tastypie的外键还可以引用自身Resource。这些都可以在tastypie的文档查得,而且tastypie外键类型不止ToMany,还有ToOne,甚至ContentType也可以创建对应的关系。
有关tastypie的外键,我还有两点需要说明,大家注意一下即可。
1、Resource中Meta的fields显示字段设置对外键字段无效。不管你设置该外键字段是否显示,它还是会显示出来。若你不想显示,可以通过dehydrate排除该字段;
2、有时需要获取列表和明细可以分别设置不同的字段显示。tastypie没有提供相应分开独立的设置。若真的需要分开设置,可以分别创建不同的Resource。其中一个Resource专门获取列表,一个获取明细。在不同的获取数据方式不想显示外键信息,可以在对于Resource中不添加外键字段设置。
Qpigzhu
😀
2018-12-06 20:32 回复
Qpigzhu
🌳
2018-12-06 20:33 回复
Qpigzhu
🍅
2018-12-06 20:33 回复
Qpigzhu
😂
2018-12-06 20:33 回复
Shonminh
阿萨德
2018-12-28 22:57 回复