DjangoRestFrameworkNotes
title: Django Rest Framework ็ฌ่ฎฐ tags:
Django
Django Rest Framework
categories:
Python
Serializers
RelationShip
# coding: utf-8
# @author bovenson
# @email [email protected]
# @desc Django Rest Framework Serializers
from rest_framework import serializers
from book.models import *
from cloudlibraryserver.settings import IMAGE_SOURCE, IMG_URL
class ScoreSerializer(serializers.ModelSerializer):
"""ไนฆ็ฑ่ฏๅ"""
class Meta:
model = BookScore
fields = '__all__'
class BookAuthorSerializer(serializers.ModelSerializer):
"""ไนฆ็ฑไฝ่
"""
class Meta:
model = BookAuthor
fields = '__all__'
class BookTagSerializer(serializers.ModelSerializer):
"""ไนฆ็ฑๆ ็ญพ"""
class Meta:
model = BookTag
fields = '__all__'
class BookSerializer(serializers.ModelSerializer):
"""ไนฆ็ฑ"""
score = ScoreSerializer(many=False, read_only=True)
author = BookAuthorSerializer(many=True, read_only=True)
tags = BookTagSerializer(many=True, read_only=True)
class Meta:
model = Book
fields = ['name', 'summary', 'pic', 'score', 'author', 'tags']
def to_representation(self, instance):
# ไฟฎๆนๅพ็URL
ret = super().to_representation(instance)
# ไธ็ๅจๅญ
if IMAGE_SOURCE == 'QINIU':
ret['pic'] = IMG_URL + ret['pic'][len('/media'):]
return ret
class BooklistSerializer(serializers.HyperlinkedModelSerializer):
"""ไนฆๅ"""
class Meta:
model = BookList
fields = ['id']
Order
class Track(models.Model):
album = models.ForeignKey(Album, related_name='tracks', on_delete=models.CASCADE)
order = models.IntegerField()
title = models.CharField(max_length=100)
duration = models.IntegerField()
class Meta:
unique_together = ('album', 'order')
ordering = ['order'] # ๅจModelๅฎไนไธญ่ฎพ็ฝฎordering
่ทๅๅไธช่ฎฐๅฝ
่ฎพ็ฝฎModelViewSet
ไนๅ๏ผไผ้ป่ฎคๅขๅ view_url/pk/
ไฝฟ็จไธๅSerilizerๅไธๆจกๅ
urls.py
# route
router.register(r'book', BookViewSet)
router.register(r'bookdetail', BookDetailViewSet, 'bookdetail')
# view set
class BookViewSet(viewsets.ModelViewSet):
"""ไนฆ็ฑ View Set"""
queryset = Book.objects.all().order_by('id')
serializer_class = BookSerializer
pagination_class = StandardResultSetPagination
class BookDetailViewSet(viewsets.ModelViewSet):
"""ไนฆ็ฑ่ฏฆๆ
"""
queryset = Book.objects.all().order_by('id')
serializer_class = BookDetailSerializer
pagination_class = StandardResultSetPagination
# serilizer
class BookSerializer(serializers.ModelSerializer):
"""ไนฆ็ฑ"""
score = ScoreSerializer(many=False, read_only=True)
author = BookAuthorSerializer(many=True, read_only=True)
tags = BookTagSerializer(many=True, read_only=True)
class Meta:
model = Book
fields = ['id', 'name', 'summary', 'pic', 'score', 'author', 'tags']
def to_representation(self, instance):
# ไฟฎๆนๅพ็URL
ret = super().to_representation(instance)
# ไธ็ๅจๅญ
if IMAGE_SOURCE == 'QINIU':
ret['pic'] = IMG_URL + ret['pic'][len('/media'):]
return ret
class BookDetailSerializer(BookSerializer): # ่ฟ้็ปงๆฟ BookSerializer
info = BookInfoSerializer(many=False, read_only=True)
"""ไนฆ็ฑ่ฏฆๆ
"""
class Meta:
model = Book
fields = ['id', 'name', 'summary', 'pic', 'score', 'author', 'tags', 'info']
่ฟๅๆ
้ๆฑๆ่ฟฐ
่ฟๅๆฐๆฎๅบ่กจไธญๆ่ฟฐ็ๅ็ฑปๆ
Model
class ArticleCategory(models.Model):
"""ๆ็ซ ๅ็ฑป"""
name = models.CharField('ๅ็ฑปๅ็งฐ', max_length=50)
children = models.ManyToManyField('self', symmetrical=False, blank=True)
def __str__(self):
return self.name
Serializer
from rest_framework import serializers
from django.contrib.auth.models import User, Group
from rest_framework_recursive.fields import RecursiveField
class ArticleCategorySerializer(serializers.ModelSerializer):
"""ๆ็ซ ๅ็ฑป"""
children = RecursiveField(many=True)
class Meta:
model = ArticleCategory
fields = '__all__'
ViewSet
class ArticleCategoryViewSet(viewsets.ModelViewSet):
"""ๆ็ซ ๅ็ฑปๅ่กจ"""
queryset = ArticleCategory.objects.all()
serializer_class = ArticleCategorySerializer
@action(methods=['GET'], detail=False)
def tree(self, request):
prefetch = ArticleCategory.objects.all().prefetch_related()
childs = list(map(lambda x: x.get('children'), prefetch.filter(children__isnull=False).values('children')))
query = prefetch.exclude(pk__in=childs)
serializer = self.get_serializer(query, many=True)
return Response(serializer.data)
้ข่ง
GET /api/article/category/tree/
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{
"id": 4,
"children": [
{
"id": 3,
"children": [
{
"id": 1,
"children": [],
"name": "A"
},
{
"id": 2,
"children": [],
"name": "Q"
}
],
"name": "B"
}
],
"name": "D"
}
]
ๅ้กต
File Tree
bovenson@ThinkCentre:~/Git/isite/Server$ tree
.
โโโ db.sqlite3
โโโ isite
โ โโโ admin.py
โ โโโ apps.py
โ โโโ core
โ โ โโโ __init__.py
โ โ โโโ pagination.py
โ โโโ __init__.py
โ โโโ models.py
โ โโโ permissions
โ โ โโโ permissions.py
โ โโโ __pycache__
โ โ โโโ admin.cpython-35.pyc
โ โ โโโ apps.cpython-35.pyc
โ โ โโโ __init__.cpython-35.pyc
โ โ โโโ models.cpython-35.pyc
โ โ โโโ urls.cpython-35.pyc
โ โโโ serializers
โ โ โโโ serializers.py
โ โโโ tests.py
โ โโโ urls.py
โ โโโ views
โ โโโ viewsets.py
โโโ isite_server
โ โโโ __init__.py
โ โโโ settings.py
โ โโโ urls.py
โ โโโ wsgi.py
โโโ manage.py
โโโ templates
่ชๅฎไนๅ้กต็ฑป
pagination.py
# coding: utf-8
# @author bovenson
# @email [email protected]
# @desc ๅ้กต
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
class StandardResultSetPagination(PageNumberPagination):
"""่ชๅฎไนๅ้กต"""
page_size = 10
page_query_param = 'page'
max_page_size = 1000
def get_paginated_response(self, data):
"""่ชๅฎไน่ฟๅไฟกๆฏ"""
return Response({
'links': {
'next': self.get_next_link(),
'previous': self.get_previous_link()
},
'count': self.page.paginator.count,
'pages': self.page.paginator.num_pages,
'results': data
})
settings
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PAGINATION_CLASS': 'isite.core.pagination.StandardResultSetPagination', # ่ฎพ็ฝฎ้ป่ฎคๅ้กต็ฑป
'PAGE_SIZE': 10
}
ๅฏนไบ่ชๅฎไนaction่ฟ่กๅ้กต
class ArticleViewSet(viewsets.ModelViewSet):
"""ๆ็ซ ViewSet"""
queryset = Article.objects.all().order_by('-create_datetime')
serializer_class = ArticleSerializer
authentication_classes = ()
@action(methods=['GET'], detail=False)
def summary(self, request):
"""่ทๅๅธฆๆ้ๅฎๅญ็ฌฆ็ฎไป็ๅ่กจ"""
articles = Article.objects.all()
for article in articles:
article.content = article.content[:120]
# ๅ้กต
page = self.paginate_queryset(articles)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
else:
serializer = self.get_serializer(articles, many=True)
return Response(serializer.data)
ๅ่
ๆๅๆดๆฐไบ
่ฟๆๅธฎๅฉๅ๏ผ