Django REST Framework图片上传Swagger无选择文件按钮问题
Django REST Framework 图片上传接口Swagger无文件选择按钮问题
问题描述
使用Django REST Framework实现Office图片上传接口,已配置MEDIA_URL和MEDIA_ROOT,但在Swagger访问/office/office/{id}/upload-image/接口时,未显示“Choose file”按钮,仅显示string($uri)输入框,无法进行文件上传操作。相关代码如下:
core/models.py
def office_image_file_path(instance, filename): ext = filename.split('.')[-1] filename = f'{uuid.uuid4()}.{ext}' return os.path.join('uploads/office/', filename) class Office(models.Model): # Other fields... image = models.ImageField(null=True, upload_to=office_image_file_path)
office/serializer.py
class OfficeSerializer(serializers.ModelSerializer): class Meta: """Meta class for OfficeSerializer.""" model = Office fields = "__all__" class OfficeImageSerializer(serializers.ModelSerializer): """Serializer for uploading images to recipes""" class Meta: model = Office fields = ('id', 'image') read_only_fields = ('id',) extra_kwargs = {'image': {'required': True}}
office/views.py
class OfficeViewSet(viewsets.ModelViewSet): """ API endpoint that allows offices to be viewed or edited if authenticated. """ queryset = Office.objects.all() serializer_class = OfficeSerializer authentication_classes = [TokenAuthentication] permission_classes = [IsAuthenticated] def get_queryset(self): """ Retrive offices for authenticated users. """ return self.queryset.filter(user=self.request.user) def get_serializer_class(self): if self.action == 'upload_image': return OfficeImageSerializer return OfficeSerializer def perform_create(self, serializer): serializer.save(user=self.request.user) @action(methods=['POST'], detail=True, url_path='upload-image') def upload_image(self, request, pk=None): office = self.get_object() print(request.data) # Debug: Print the request data serializer = self.get_serializer( office, data=request.data ) if serializer.is_valid(): serializer.save() return Response( serializer.data, status=status.HTTP_200_OK ) return Response( serializer.errors, status=status.HTTP_400_BAD_REQUEST )
解决方法
方法1:为ImageField指定Swagger文件类型注解
修改OfficeImageSerializer,明确告诉Swagger该字段为文件上传类型:
from drf_yasg import openapi class OfficeImageSerializer(serializers.ModelSerializer): """Serializer for uploading images to recipes""" image = serializers.ImageField( required=True, swagger_schema_fields={ 'type': 'file', 'description': 'Office image file' } ) class Meta: model = Office fields = ('id', 'image') read_only_fields = ('id',)
方法2:在视图动作上配置请求体格式
在upload_image动作中,手动指定请求体为multipart/form-data类型:
from drf_yasg.utils import swagger_auto_schema from drf_yasg import openapi class OfficeViewSet(viewsets.ModelViewSet): # ... 其他代码 ... @swagger_auto_schema( request_body=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'image': openapi.Schema(type=openapi.TYPE_FILE, description='Image file') }, required=['image'] ), consumes=['multipart/form-data'] ) @action(methods=['POST'], detail=True, url_path='upload-image') def upload_image(self, request, pk=None): # ... 原有代码 ...
方法3:检查DRF-YASG基础配置
确保项目已安装drf-yasg,并在urls.py中正确配置Swagger视图:
from drf_yasg.views import get_schema_view from drf_yasg import openapi from rest_framework import permissions schema_view = get_schema_view( openapi.Info( title="Office API", default_version='v1', description="API for office management", ), public=True, permission_classes=[permissions.AllowAny], ) urlpatterns = [ # ... 其他路由 ... path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), ]
原理说明
Swagger默认会将ImageField解析为字符串类型(URI),因为DRF序列化ImageField时返回的是图片URL。但上传场景需要明确指定字段为文件类型,并要求使用multipart/form-data格式接收请求,通过上述配置即可让Swagger显示文件选择按钮。
内容的提问来源于stack exchange,提问作者joaovitorpigozzo
相关产品推荐
相关产品推荐

