tastypie中model之间的关系

  • 发布时间:2017年8月4日 01:15
  • 作者:杨仕航
  • 分类标签: Django
  • 阅读(7531)
  • 评论(5)

接着上一篇初步使用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中不添加外键字段设置。

上一篇:充分利用Excel的布尔值

下一篇:初步使用tastypie的体悟

评论列表

Qpigzhu

Qpigzhu

😀

2018-12-06 20:32 回复

Qpigzhu

Qpigzhu

🌳

2018-12-06 20:33 回复

Qpigzhu

Qpigzhu

🍅

2018-12-06 20:33 回复

  • Qpigzhu

    😂

    2018-12-06 20:33 回复

Shonminh

Shonminh

阿萨德

2018-12-28 22:57 回复

新的评论

清空