辞書のupdateメソッド
既存キーの値を上書きしたり、新規キー・バリューを追加する機能を持つ。引数には辞書やキー・バリューのイテラブルを受け取り、戻り値はなし。
d = {'apple': 1}
d.update({'banana': 2})
d.update(apple='red')
print(d) # {'apple': 'red', 'banana': 2}
外部キー関連データの深層取得手法
- ネストしたシリアライザを使用
- depthオプションで階層指定
- @propertyデコレータで動的フィールド生成
DRFにおける一括操作API設計
class BookAPIView(APIView):
def delete(self, request, *args, **kwargs):
target_ids = [kwargs.get('pk')] if kwargs.get('pk') else request.data
updated_count = Book.objects.filter(
is_deleted=False,
id__in=target_ids
).update(is_deleted=True)
return Response({
'status': 'success' if updated_count else 'failed',
'affected': updated_count
})
def post(self, request, *args, **kwargs):
is_bulk = isinstance(request.data, list)
serializer = BookSerializer(
data=request.data,
many=is_bulk
)
serializer.is_valid(raise_exception=True)
saved_items = serializer.save()
return Response(BookSerializer(
saved_items,
many=is_bulk
).data)
def put(self, request, *args, **kwargs):
items = request.data if isinstance(request.data, list) else [request.data]
item_ids = []
for item in items:
item_ids.append(item.pop('id'))
existing_books = Book.objects.filter(id__in=item_ids)
if len(existing_books) != len(item_ids):
raise ValidationError("一部のIDが存在しません")
serializer = BookSerializer(
existing_books,
data=items,
many=True
)
serializer.is_valid(raise_exception=True)
updated_books = serializer.save()
return Response(BookSerializer(updated_books, many=True).data)
many=True時の内部処理フロー解析
class BaseSerializer:
def __new__(cls, *args, **kwargs):
if kwargs.pop('many', False):
return cls.create_list_serializer(*args, **kwargs)
return super().__new__(cls)
@classmethod
def create_list_serializer(cls, *args, **kwargs):
child_instance = cls(*args, **kwargs)
meta = getattr(cls, 'Meta', None)
list_class = getattr(meta, 'list_serializer_class', ListSerializer)
return list_class(child=child_instance, *args, **kwargs)
class CustomListSerializer(serializers.ListSerializer):
def update(self, instances, validated_data):
return [
self.child.update(instances[i], data)
for i, data in enumerate(validated_data)
]
class BookSerializer(serializers.ModelSerializer):
title = serializers.CharField(max_length=64) # unique制約を回避
class Meta:
list_serializer_class = CustomListSerializer
ハマりやすいユニーク制約の問題
ModelSerializerでunique=Trueなフィールドを扱う際、明示的にフィールド定義しないとモデルレベルの制約が適用され、更新時に誤って重複エラーが発生することがある。明示的なフィールド宣言でこの挙動を抑制できる。