Django REST Framework (DRF) ã§ã®ãã¹ãããããªããžã§ã¯ãã·ãªã¢ã©ã€ãŒãŒã·ã§ã³ã®å æ¬çãªã¬ã€ããã·ãªã¢ã©ã€ã¶ãŒãããŸããŸãªãªã¬ãŒã·ã§ã³ã¿ã€ããé«åºŠãªãã¯ããã¯ãã«ããŒã
Python DRF ã·ãªã¢ã©ã€ã¶ãŒã®ãªã¬ãŒã·ã§ã³: ãã¹ãããããªããžã§ã¯ãã·ãªã¢ã©ã€ãŒãŒã·ã§ã³ã®ç¿åŸ
Django REST Framework (DRF) ã¯ããŠã§ã API ãæ§ç¯ããããã®åŒ·åã§æè»ãªã·ã¹ãã ãæäŸããŸãã API éçºã®éèŠãªåŽé¢ã¯ãããŒã¿ã¢ãã«éã®é¢ä¿ãåŠçããããšã§ãããDRF ã·ãªã¢ã©ã€ã¶ãŒã¯ããã¹ãããããªããžã§ã¯ãã®ã·ãªã¢ã©ã€ãºãšãã·ãªã¢ã©ã€ãºã®ããã®å ç¢ãªã¡ã«ããºã ãæäŸããŸãã ãã®ã¬ã€ãã§ã¯ãDRF ã·ãªã¢ã©ã€ã¶ãŒã§ãªã¬ãŒã·ã§ã³ã管çããããŸããŸãªæ¹æ³ãæ¢ããå®è·µçãªäŸãšãã¹ããã©ã¯ãã£ã¹ãæäŸããŸãã
ã·ãªã¢ã©ã€ã¶ãŒãªã¬ãŒã·ã§ã³ã®çè§£
ãªã¬ãŒã·ã§ãã«ããŒã¿ããŒã¹ã§ã¯ããªã¬ãŒã·ã§ã³ã«ãã£ãŠããŸããŸãªããŒãã«ãŸãã¯ã¢ãã«ãã©ã®ããã«æ¥ç¶ãããŠããããå®çŸ©ãããŸãã DRF ã·ãªã¢ã©ã€ã¶ãŒã¯ãAPI æ¶è²»ã®ããã«ããŒã¿ããŒã¹ãªããžã§ã¯ãã JSON ãŸãã¯ãã®ä»ã®ããŒã¿åœ¢åŒã«å€æããéã«ããããã®ãªã¬ãŒã·ã§ã³ãåæ ããå¿ èŠããããŸãã 3 ã€ã®äž»èŠãªãªã¬ãŒã·ã§ã³ã¿ã€ãã«ã€ããŠèª¬æããŸãã
- ForeignKey (One-to-Many): 1 ã€ã®ãªããžã§ã¯ãããä»ã®è€æ°ã®ãªããžã§ã¯ãã«é¢é£ä»ããããŠããŸãã ããšãã°ã1 人ã®èè ã倿°ã®æ¬ãæžãããšãã§ããŸãã
- ManyToManyField (Many-to-Many): è€æ°ã®ãªããžã§ã¯ãããä»ã®è€æ°ã®ãªããžã§ã¯ãã«é¢é£ä»ããããŠããŸãã ããšãã°ãè€æ°ã®èè ãè€æ°ã®æ¬ã§å ±åäœæ¥ãè¡ãããšãã§ããŸãã
- OneToOneField (One-to-One): 1 ã€ã®ãªããžã§ã¯ããäžæã«å¥ã®ãªããžã§ã¯ãã«é¢é£ä»ããããŠããŸãã ããšãã°ããŠãŒã¶ãŒãããã¡ã€ã«ã¯ãå€ãã®å ŽåããŠãŒã¶ãŒã¢ã«ãŠã³ããš 1 察 1 ã§ãªã³ã¯ãããŸãã
ForeignKey ã䜿çšããåºæ¬çãªãã¹ããããã·ãªã¢ã©ã€ãŒãŒã·ã§ã³
ForeignKey ãªã¬ãŒã·ã§ã³ãã·ãªã¢ã©ã€ãºããç°¡åãªäŸããå§ããŸãããã ãããã®ã¢ãã«ãæ€èšããŠãã ããã
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
country = models.CharField(max_length=50, default='USA') # åœéçãªã³ã³ããã¹ãã®ããã«åœãã£ãŒã«ãã远å
def __str__(self):
return self.name
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')
publication_date = models.DateField()
def __str__(self):
return self.title
é¢é£ãã `Author` ããŒã¿ãšãšãã« `Book` ã¢ãã«ãã·ãªã¢ã©ã€ãºããã«ã¯ããã¹ããããã·ãªã¢ã©ã€ã¶ãŒã䜿çšã§ããŸãã
from rest_framework import serializers
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = ['id', 'name', 'country']
class BookSerializer(serializers.ModelSerializer):
author = AuthorSerializer(read_only=True) # PrimaryKeyRelatedField ãã倿Ž
class Meta:
model = Book
fields = ['id', 'title', 'author', 'publication_date']
ãã®äŸã§ã¯ã`BookSerializer` ã« `AuthorSerializer` ãã£ãŒã«ããå«ãŸããŠããŸãã `read_only=True` ã¯ã`author` ãã£ãŒã«ããèªã¿åãå°çšã«ããæžç±ãšã³ããã€ã³ããä»ããèè ã®å€æŽãé²ããŸãã èè ã®æ å ±ã§æžç±ãäœæãŸãã¯æŽæ°ããå¿ èŠãããå Žåã¯ãæžãèŸŒã¿æäœãå¥ã®æ¹æ³ã§åŠçããå¿ èŠããããŸã (以äžãåç §)ã
次ã«ã`Book` ãªããžã§ã¯ããã·ãªã¢ã©ã€ãºãããšãJSON åºåã«ã¯ãæžç±ããŒã¿å ã«ãã¹ããããå®å šãªèè ã®è©³çްãå«ãŸããŸãã
{
"id": 1,
"title": "The Hitchhiker's Guide to the Galaxy",
"author": {
"id": 1,
"name": "Douglas Adams",
"country": "UK"
},
"publication_date": "1979-10-12"
}
ManyToManyField ãªã¬ãŒã·ã§ã³ã®ã·ãªã¢ã©ã€ãŒãŒã·ã§ã³
`ManyToManyField` ãªã¬ãŒã·ã§ã³ã«ã€ããŠèããŠã¿ãŸãããã `Category` ã¢ãã«ããããæžç±ãè€æ°ã®ã«ããŽãªã«å±ããããšãã§ãããšããŸãã
class Category(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')
categories = models.ManyToManyField(Category, related_name='books')
publication_date = models.DateField()
def __str__(self):
return self.title
`serializers.StringRelatedField` ãŸã㯠`serializers.PrimaryKeyRelatedField` ã䜿çšããŠã«ããŽãªãã·ãªã¢ã©ã€ãºãããããã¹ããããã·ãªã¢ã©ã€ã¶ãŒãäœæã§ããŸãã
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ['id', 'name']
class BookSerializer(serializers.ModelSerializer):
author = AuthorSerializer(read_only=True)
categories = CategorySerializer(many=True, read_only=True) # ManyToManyField ã«ã¯ many=True ãäžå¯æ¬
class Meta:
model = Book
fields = ['id', 'title', 'author', 'categories', 'publication_date']
`ManyToManyField` ãã·ãªã¢ã©ã€ãºããå Žåã`many=True` åŒæ°ã¯éåžžã«éèŠã§ãã ããã¯ãã·ãªã¢ã©ã€ã¶ãŒã«ã«ããŽãªãªããžã§ã¯ãã®ãªã¹ããæ³å®ããããã«æç€ºããŸãã åºåã¯æ¬¡ã®ããã«ãªããŸãã
{
"id": 1,
"title": "Pride and Prejudice",
"author": {
"id": 2,
"name": "Jane Austen",
"country": "UK"
},
"categories": [
{
"id": 1,
"name": "Classic Literature"
},
{
"id": 2,
"name": "Romance"
}
],
"publication_date": "1813-01-28"
}
OneToOneField ãªã¬ãŒã·ã§ã³ã®ã·ãªã¢ã©ã€ãŒãŒã·ã§ã³
`OneToOneField` ãªã¬ãŒã·ã§ã³ã®å Žåãã¢ãããŒã㯠ForeignKey ã«äŒŒãŠããŸãããé¢é£ãªããžã§ã¯ããååšããªãå¯èœæ§ãããã±ãŒã¹ãåŠçããããšãéèŠã§ãã
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
bio = models.TextField(blank=True)
location = models.CharField(max_length=100, blank=True, default='Global') # åœéçãªã³ã³ããã¹ãã®ããã«å Žæã远å
def __str__(self):
return self.user.username
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ['id', 'bio', 'location']
class UserSerializer(serializers.ModelSerializer):
profile = UserProfileSerializer(read_only=True)
class Meta:
model = User
fields = ['id', 'username', 'email', 'profile']
åºåã¯æ¬¡ã®ããã«ãªããŸãã
{
"id": 1,
"username": "johndoe",
"email": "john.doe@example.com",
"profile": {
"id": 1,
"bio": "Software Engineer.",
"location": "London, UK"
}
}
æžãèŸŒã¿æäœã®åŠç (äœæãšæŽæ°)
äžèšã®äŸã¯ãäž»ã«èªã¿åãå°çšã®ã·ãªã¢ã©ã€ãŒãŒã·ã§ã³ã«çŠç¹ãåœãŠãŠããŸãã é¢é£ãªããžã§ã¯ãã®äœæãŸãã¯æŽæ°ãèš±å¯ããã«ã¯ãã·ãªã¢ã©ã€ã¶ãŒã§ `create()` ããã³ `update()` ã¡ãœããããªãŒããŒã©ã€ãããå¿ èŠããããŸãã
ãã¹ãããããªããžã§ã¯ãã®äœæ
æ°ããæžç±ãšèè ãåæã«äœæãããšããŸãã
class BookSerializer(serializers.ModelSerializer):
author = AuthorSerializer()
class Meta:
model = Book
fields = ['id', 'title', 'author', 'publication_date']
def create(self, validated_data):
author_data = validated_data.pop('author')
author = Author.objects.create(**author_data)
book = Book.objects.create(author=author, **validated_data)
return book
`create()` ã¡ãœããã§ã¯ãèè ã®ããŒã¿ãæœåºããæ°ãã `Author` ãªããžã§ã¯ããäœæããæ¬¡ã« `Book` ãªããžã§ã¯ããäœæããæ°ããäœæãããèè ã«é¢é£ä»ããŸãã
éèŠ: `author_data` ã§æœåšçãªæ€èšŒãšã©ãŒãåŠçããå¿ èŠããããŸãã try-except ãããã¯ã䜿çšããèè ã®ããŒã¿ãç¡å¹ãªå Žå㯠`serializers.ValidationError` ãçºçãããããšãã§ããŸãã
ãã¹ãããããªããžã§ã¯ãã®æŽæ°
åæ§ã«ãæžç±ãšãã®èè äž¡æ¹ãæŽæ°ããã«ã¯ã次ã®ããã«ããŸãã
class BookSerializer(serializers.ModelSerializer):
author = AuthorSerializer()
class Meta:
model = Book
fields = ['id', 'title', 'author', 'publication_date']
def update(self, instance, validated_data):
author_data = validated_data.pop('author', None)
if author_data:
author = instance.author
for attr, value in author_data.items():
setattr(author, attr, value)
author.save()
for attr, value in validated_data.items():
setattr(instance, attr, value)
instance.save()
return instance
`update()` ã¡ãœããã§ã¯ãæ¢åã®èè ãæ€çŽ¢ããæäŸãããããŒã¿ã«åºã¥ããŠãã®å±æ§ãæŽæ°ããæ¬¡ã«æžç±ã®å±æ§ãæŽæ°ããŸãã `author_data` ãæäŸãããŠããªãå Žå (ã€ãŸããèè ãæŽæ°ãããŠããªãå Žå)ãã³ãŒãã¯èè ã®æŽæ°ã»ã¯ã·ã§ã³ãã¹ãããããŸãã `validated_data.pop('author', None)` ã® `None` ããã©ã«ãã¯ãèè ã®ããŒã¿ãæŽæ°ãªã¯ãšã¹ãã«å«ãŸããŠããªãã±ãŒã¹ãåŠçããããã«äžå¯æ¬ ã§ãã
`PrimaryKeyRelatedField` ã®äœ¿çš
ãã¹ããããã·ãªã¢ã©ã€ã¶ãŒã®ä»£ããã«ã`PrimaryKeyRelatedField` ã䜿çšããŠãé¢é£ãªããžã§ã¯ãã®äž»ããŒã䜿çšããŠãªã¬ãŒã·ã§ã³ã衚ãããšãã§ããŸãã ããã¯ãé¢é£ãªããžã§ã¯ãã® ID ã®ã¿ãåç §ããå¿ èŠãããããªããžã§ã¯ãå šäœãã·ãªã¢ã©ã€ãºããããªãå Žåã«äŸ¿å©ã§ãã
class BookSerializer(serializers.ModelSerializer):
author = serializers.PrimaryKeyRelatedField(queryset=Author.objects.all())
class Meta:
model = Book
fields = ['id', 'title', 'author', 'publication_date']
ããã§ã`author` ãã£ãŒã«ãã«ã¯èè ã® ID ãå«ãŸããŸãã
{
"id": 1,
"title": "1984",
"author": 3, // èè
ã® ID
"publication_date": "1949-06-08"
}
äœæãšæŽæ°ã®å Žåããªã¯ãšã¹ãããŒã¿ã§èè ã® ID ãæž¡ããŸãã `queryset=Author.objects.all()` ã«ãããæäŸããã ID ãããŒã¿ããŒã¹ã«ååšããããšãä¿èšŒãããŸãã
`HyperlinkedRelatedField` ã®äœ¿çš
`HyperlinkedRelatedField` ã¯ãé¢é£ãªããžã§ã¯ãã® API ãšã³ããã€ã³ããžã®ãã€ããŒãªã³ã¯ã䜿çšããŠãªã¬ãŒã·ã§ã³ã衚ããŸãã ããã¯ããã€ããŒã¡ãã£ã¢ API (HATEOAS) ã§ãã䜿çšãããŸãã
class BookSerializer(serializers.ModelSerializer):
author = serializers.HyperlinkedRelatedField(view_name='author-detail', read_only=True)
class Meta:
model = Book
fields = ['id', 'title', 'author', 'publication_date']
`view_name` åŒæ°ã¯ãé¢é£ãªããžã§ã¯ãã®ãªã¯ãšã¹ããåŠçãããã¥ãŒã®ååãæå®ããŸã (äŸ: `author-detail`)ã `urls.py` ã§ãã®ãã¥ãŒãå®çŸ©ããå¿ èŠããããŸãã
åºåã«ã¯ãèè ã®è©³çްãšã³ããã€ã³ããæã URL ãå«ãŸããŸãã
{
"id": 1,
"title": "Brave New World",
"author": "http://example.com/api/authors/4/",
"publication_date": "1932-01-01"
}
é«åºŠãªãã¯ããã¯ãšèæ ®äºé
- `depth` ãªãã·ã§ã³: `ModelSerializer` ã§ã¯ã`depth` ãªãã·ã§ã³ã䜿çšããŠãForeignKey ãªã¬ãŒã·ã§ã³ã®ãã¹ããããã·ãªã¢ã©ã€ã¶ãŒãç¹å®ã®æ·±ããŸã§èªåçã«äœæã§ããŸãã ãã ãã`depth` ã䜿çšãããšããªã¬ãŒã·ã§ã³ãè€éãªå Žåã«ããã©ãŒãã³ã¹ã®åé¡ãçºçããå¯èœæ§ããããããéåžžã¯ã·ãªã¢ã©ã€ã¶ãŒãæç€ºçã«å®çŸ©ããããšããå§ãããŸãã
- `SerializerMethodField`: `SerializerMethodField` ã䜿çšããŠãé¢é£ããŒã¿ã®ã«ã¹ã¿ã ã·ãªã¢ã©ã€ãŒãŒã·ã§ã³ããžãã¯ãäœæããŸãã ããã¯ãããŒã¿ãç¹å®ã®åœ¢åŒã§ãã©ãŒãããããããèšç®ãããå€ãå«ãããããå¿ èŠãããå Žåã«äŸ¿å©ã§ãã ããšãã°ããã±ãŒã«ã«åºã¥ããŠèè ã®æ°åãç°ãªãé åºã§è¡šç€ºã§ããŸãã å€ãã®ã¢ãžã¢æåã§ã¯ãå§ãååã«å è¡ããŸãã
- 衚çŸã®ã«ã¹ã¿ãã€ãº: ã·ãªã¢ã©ã€ã¶ãŒã® `to_representation()` ã¡ãœããããªãŒããŒã©ã€ãããŠãé¢é£ããŒã¿ã®è¡šçŸæ¹æ³ãã«ã¹ã¿ãã€ãºããŸãã
- ããã©ãŒãã³ã¹ã®æé©å: è€éãªãªã¬ãŒã·ã§ã³ãšå€§èŠæš¡ãªããŒã¿ã»ããã®å Žåãselect_related ãš prefetch_related ãªã©ã®ææ³ã䜿çšããŠãããŒã¿ããŒã¹ã¯ãšãªãæé©åããããŒã¿ããŒã¹ãããæ°ãæžãããŸãã ããã¯ãæ¥ç¶é床ãé ãå¯èœæ§ãããã°ããŒãã«ãŠãŒã¶ãŒã«ãµãŒãã¹ãæäŸãã API ã«ãšã£ãŠç¹ã«éèŠã§ãã
- NULL å€ã®åŠç: ç¹ã«ãªãã·ã§ã³ã®ãªã¬ãŒã·ã§ã³ãæ±ãå Žåã¯ãã·ãªã¢ã©ã€ã¶ãŒã§ã® NULL å€ã®åŠçã«æ³šæããŠãã ããã å¿ èŠã«å¿ããŠãã·ãªã¢ã©ã€ã¶ãŒãã£ãŒã«ãã§ `allow_null=True` ã䜿çšããŸãã
- æ€èšŒ: ããŒã¿ã®æŽåæ§ã確ä¿ããããã«ãç¹ã«é¢é£ãªããžã§ã¯ããäœæãŸãã¯æŽæ°ããå Žåã¯ãå ç¢ãªæ€èšŒãå®è£ ããŸãã ã«ã¹ã¿ã ããªããŒã¿ã䜿çšããŠãããžãã¹ã«ãŒã«ãé©çšããããšãæ€èšããŠãã ããã ããšãã°ãæžç±ã®åºçæ¥ã¯æªæ¥ã§ãã£ãŠã¯ãªããŸããã
- åœéåãšããŒã«ã©ã€ãº (i18n/l10n): ããŒã¿ãããŸããŸãªèšèªãšå°åã§ã©ã®ããã«è¡šç€ºãããããæ€èšããŸãã æ¥ä»ãæ°å€ãé貚ããŠãŒã¶ãŒã®ãã±ãŒã«ã«åãããŠé©åã«ãã©ãŒãããããŸãã åœéåå¯èœãªæååãã¢ãã«ãšã·ãªã¢ã©ã€ã¶ãŒã«æ ŒçŽããŸãã
ã·ãªã¢ã©ã€ã¶ãŒãªã¬ãŒã·ã§ã³ã®ãã¹ããã©ã¯ãã£ã¹
- ã·ãªã¢ã©ã€ã¶ãŒãçŠç¹ãçµã£ããã®ã«ãã: åã·ãªã¢ã©ã€ã¶ãŒã¯ãç¹å®ã®ã¢ãã«ãŸãã¯å¯æ¥ã«é¢é£ããããŒã¿ã»ãããã·ãªã¢ã©ã€ãºãã責任ãè² ããŸãã é床ã«è€éãªã·ãªã¢ã©ã€ã¶ãŒã®äœæã¯é¿ããŠãã ããã
- æç€ºçãªã·ãªã¢ã©ã€ã¶ãŒã䜿çšãã: `depth` ãªãã·ã§ã³ã«é床ã«äŸåããªãããã«ããŠãã ããã åé¢é£ã¢ãã«ã®æç€ºçãªã·ãªã¢ã©ã€ã¶ãŒãå®çŸ©ããŠãã·ãªã¢ã©ã€ãŒãŒã·ã§ã³ããã»ã¹ããã现ããå¶åŸ¡ã§ããããã«ããŸãã
- 培åºçã«ãã¹ããã: ç¹ã«è€éãªãªã¬ãŒã·ã§ã³ãæ±ãå Žåã¯ãã·ãªã¢ã©ã€ã¶ãŒãããŒã¿ãæ£ããã·ãªã¢ã©ã€ãºããã³ãã·ãªã¢ã©ã€ãºããŠããããšã確èªããããã®åäœãã¹ããäœæããŸãã
- API ãææžåãã: API ãšã³ããã€ã³ããšãããããæåŸ ããã³è¿ãããŒã¿åœ¢åŒãæç¢ºã«ææžåããŸãã Swagger ãŸã㯠OpenAPI ãªã©ã®ããŒã«ã䜿çšããŠãã€ã³ã¿ã©ã¯ãã£ã㪠API ããã¥ã¡ã³ããçæããŸãã
- API ããŒãžã§ã³ç®¡çãæ€èšãã: API ãé²åããã«ã€ããŠãããŒãžã§ã³ç®¡çã䜿çšããŠæ¢åã®ã¯ã©ã€ã¢ã³ããšã®äºææ§ãç¶æããŸãã ããã«ãããå€ãã¢ããªã±ãŒã·ã§ã³ã«åœ±é¿ãäžããããšãªããç Žå£çãªå€æŽãå°å ¥ã§ããŸãã
- ããã©ãŒãã³ã¹ãç£èŠãã: API ã®ããã©ãŒãã³ã¹ãç£èŠããã·ãªã¢ã©ã€ã¶ãŒãªã¬ãŒã·ã§ã³ã«é¢é£ããããã«ããã¯ãç¹å®ããŸãã ãããã¡ã€ãªã³ã°ããŒã«ã䜿çšããŠãããŒã¿ããŒã¹ã¯ãšãªãšã·ãªã¢ã©ã€ãŒãŒã·ã§ã³ããžãã¯ãæé©åããŸãã
çµè«
Django REST Framework ã§ã·ãªã¢ã©ã€ã¶ãŒãªã¬ãŒã·ã§ã³ãç¿åŸããããšã¯ãå ç¢ã§å¹ççãªãŠã§ã API ãæ§ç¯ããããã«äžå¯æ¬ ã§ãã DRF ã·ãªã¢ã©ã€ã¶ãŒã§å©çšå¯èœãªããŸããŸãªãªã¬ãŒã·ã§ã³ã®çš®é¡ãšããŸããŸãªãªãã·ã§ã³ãçè§£ããããšã«ããããã¹ãããããªããžã§ã¯ãã广çã«ã·ãªã¢ã©ã€ãºããã³ãã·ãªã¢ã©ã€ãºããæžãèŸŒã¿æäœãåŠçããAPI ã®ããã©ãŒãã³ã¹ãæé©åã§ããŸãã API ãã°ããŒãã«ãªãªãŒãã£ãšã³ã¹ã«ã¢ã¯ã»ã¹ã§ããããã«ããããã«ãAPI ãèšèšãããšãã¯ãåœéåãšããŒã«ã©ã€ãºãèæ ®ããããšãå¿ããªãã§ãã ããã 培åºçãªãã¹ããšæç¢ºãªããã¥ã¡ã³ãã¯ãAPI ã®é·æçãªä¿å®æ§ãšäœ¿ããããã確ä¿ããããã®éµã§ãã