@python_2_unicode_compatible
class AuthorModel(models.Model):
first_name = models.CharField(max_length=50,
verbose_name=_('First Name'), )
last_name = models.CharField(max_length=50,
verbose_name=_('Last Name'), )
class Meta:
ordering = ('pk',)
unique_together = ('first_name', 'last_name')
verbose_name = _('Author')
verbose_name_plural = _('Authors')
def __str__(self):
return '{} {}'.format(self.first_name, self.last_name)
def get_absolute_url(self):
return reverse('author:author_detail', args=(self.pk,))
def get_name(self):
return '{} {}'.format(self.first_name, self.last_name)
def get_book_count(self):
return self.books.count()
def get_books_url(self):
return reverse('author:author_book_list', args=(self.pk,))
@python_2_unicode_compatible
class BookModel(models.Model):
isbn = models.CharField(max_length=25,
validators=[isbn_validator],
verbose_name=_('ISBN'),
db_index=True,
unique=True)
title = models.CharField(max_length=35,
verbose_name=_('Title'), )
author = models.ForeignKey(AuthorModel,
related_name='books',
verbose_name=_('Author'), )
description = models.TextField(verbose_name=_('Description'), )
class Meta:
ordering = ('pk',)
verbose_name = _('Book')
verbose_name_plural = _('Books')
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('book:book_detail', args=(self.isbn,))
def get_name(self):
return self.title
class AuthorSerializer(serializers.ModelSerializer):
name = serializers.CharField(source='get_name', read_only=True)
url = serializers.CharField(source='get_absolute_url', read_only=True)
book_count = serializers.CharField(source='get_book_count', read_only=True)
books_url = serializers.CharField(source='get_books_url', read_only=True)
class Meta:
model = AuthorModel
exclude = ('first_name', 'last_name')
[
{
"id": 1,
"name": "Mark Twain",
"url": "/api/v1.0/authors/1/",
"book_count": "4",
"books_url": "/api/v1.0/authors/1/books/"
},
{
"id": 2,
"name": "Isaac Asimov",
"url": "/api/v1.0/authors/2/",
"book_count": "5",
"books_url": "/api/v1.0/authors/2/books/"
}
]
[
{
"id": 2,
"name": "Isaac Asimov",
"url": "/api/v1.0/authors/2/",
"books": [
{'title':'The Naked Sun', 'url':'api/v1.0/books/9780449242438/'},
{'title':'I, Robot', 'url':'api/v1.0/books/9780246121004/'}
]
}
]
class BookSerializer(serializers.ModelSerilaizer):
class Meta:
model = Book
fields = ('id', 'title', 'url')
class AuthorSerializer(serializers.ModelSerializer):
name = serializers.CharField(source='get_name', read_only=True)
url = serializers.CharField(source='get_absolute_url', read_only=True)
book_count = serializers.CharField(source='get_book_count', read_only=True)
books_url = serializers.CharField(source='get_books_url', read_only=True)
books = BookSerializer(many=True, read_only=True)
class Meta:
model = AuthorModel
exclude = ('first_name', 'last_name')
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from rest_framework import serializers
from src.apps.book.models import AuthorModel, BookModel
class BookAuthorSerializer(serializers.ModelSerializer):
url = serializers.CharField(source='get_absolute_url', read_only=True)
name = serializers.CharField(source='get_name', read_only=True)
class Meta:
model = AuthorModel
exclude = ('id', 'first_name', 'last_name')
class BookSerializer(serializers.ModelSerializer):
url = serializers.CharField(source='get_absolute_url', read_only=True)
author = BookAuthorSerializer()
class Meta:
model = BookModel
fields = '__all__'
class AuthorBookSerializer(serializers.ModelSerializer):
url = serializers.CharField(source='get_absolute_url', read_only=True)
class Meta:
model = BookModel
exclude = ('isbn', 'author')
class AuthorListSerializer(serializers.ModelSerializer):
name = serializers.CharField(source='get_name', read_only=True)
url = serializers.CharField(source='get_absolute_url', read_only=True)
book_count = serializers.CharField(source='get_book_count', read_only=True)
class Meta:
model = AuthorModel
exclude = ('first_name', 'last_name')
class AuthorRetrieveSerializer(AuthorListSerializer):
books = AuthorBookSerializer(many=True, read_only=True)
class Meta:
model = AuthorModel
exclude = ('book_count', 'first_name', 'last_name')
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from rest_framework import viewsets
from rest_framework_extensions.mixins import DetailSerializerMixin
from src.apps.book.models import AuthorModel, BookModel
from src.apps.book.permissions import IsAccountAdminOrReadOnly
from src.apps.book.serializers import AuthorListSerializer, AuthorRetrieveSerializer, BookSerializer
class AuthorViewSet(DetailSerializerMixin, viewsets.ModelViewSet):
model = AuthorModel
queryset = AuthorModel.objects.prefetch_related('books').all()
serializer_class = AuthorListSerializer
serializer_detail_class = AuthorRetrieveSerializer
permission_classes = [
IsAccountAdminOrReadOnly
]
lookup_field = 'id'
class BookViewSet(viewsets.ModelViewSet):
model = BookModel
queryset = BookModel.objects.select_related('author').all()
serializer_class = BookSerializer
permission_classes = [
IsAccountAdminOrReadOnly
]
lookup_field = 'isbn'