基于Django REST实现Android端用户图片上传至指定用户的方案问询
实现移动端图片上传并关联用户的方案
结合你现有的Django REST框架代码和Android应用场景,我给你梳理一套完整的落地步骤:
1. 扩展后端模型与序列化器
首先需要新增一个存储用户图片的模型,和现有krisi_user做关联:
修改 models.py
from django.db import models class krisi_user(models.Model): full_name = models.CharField(max_length=250) email = models.CharField(max_length=100) def __str__(self): return self.full_name # 新增图片模型,关联到用户 class UserImage(models.Model): user = models.ForeignKey(krisi_user, on_delete=models.CASCADE, related_name='images') image = models.ImageField(upload_to='user_images/%Y/%m/%d/') # 按日期分文件夹,避免文件名冲突 uploaded_at = models.DateTimeField(auto_now_add=True) def __str__(self): return f"{self.user.full_name}'s image"
更新 Serializer.py
创建图片序列化器,同时给用户序列化器添加嵌套字段,方便返回用户的所有图片:
from rest_framework import serializers from .models import krisi_user, UserImage class UserImageSerializer(serializers.ModelSerializer): class Meta: model = UserImage fields = ('id', 'image', 'uploaded_at') class krisi_user_searializers(serializers.ModelSerializer): # 嵌套用户的图片列表,只读属性 images = UserImageSerializer(many=True, read_only=True) class Meta: model = krisi_user fields = ('id','full_name','email', 'images')
2. 实现图片上传视图与权限控制
编写处理图片上传的视图,确保只有已登录用户能上传并关联到自己的账号:
修改 views.py
from django.shortcuts import render from rest_framework import viewsets, permissions from .models import krisi_user, UserImage from .serializers import krisi_user_searializers, UserImageSerializer class krisi_user_view(viewsets.ModelViewSet): queryset = krisi_user.objects.all() serializer_class = krisi_user_searializers # 可选:限制仅登录用户访问用户接口,根据你的业务需求调整 permission_classes = [permissions.IsAuthenticated] # 图片上传视图集 class UserImageViewSet(viewsets.ModelViewSet): queryset = UserImage.objects.all() serializer_class = UserImageSerializer permission_classes = [permissions.IsAuthenticated] # 仅登录用户可操作 def perform_create(self, serializer): # 自动将当前登录用户关联到上传的图片 serializer.save(user=self.request.user) # 可选:只返回当前用户的图片,避免用户看到其他人的内容 def get_queryset(self): return self.queryset.filter(user=self.request.user)
3. 配置Django媒体文件服务
Django需要配置媒体文件的存储路径和访问路由,才能正确处理图片上传和前端访问:
修改 settings.py
添加以下配置:
# 媒体文件本地存储路径 MEDIA_ROOT = BASE_DIR / 'media' # 媒体文件访问URL前缀 MEDIA_URL = '/media/'
修改项目根目录的 urls.py
添加媒体文件的路由(仅开发环境使用,生产环境建议用Nginx或云存储处理):
from django.conf import settings from django.conf.urls.static import static from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('your_app_name.urls')), # 替换成你的实际APP名称 ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
4. Android端上传图片的实现
在Android端用Retrofit发送multipart/form-data请求,同时带上谷歌登录的认证token,确保Django能识别当前用户:
定义Retrofit接口
import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.Call import retrofit2.http.Multipart import retrofit2.http.POST import retrofit2.http.Header interface ImageUploadApi { @Multipart @POST("api/userimages/") fun uploadImage( @Header("Authorization") token: String, // 谷歌登录的Bearer token,格式为"Bearer xxx" @Part image: MultipartBody.Part ): Call<ImageResponse> // ImageResponse是你自定义的响应实体类 }
上传图片的代码示例
// 构建图片请求体 val file = File(imageLocalPath) val requestFile = RequestBody.create(MediaType.parse("image/*"), file) val imagePart = MultipartBody.Part.createFormData("image", file.name, requestFile) // 获取已存储的谷歌登录token val googleAuthToken = "Bearer ${yourSavedGoogleToken}" // 调用接口上传 val api = RetrofitClient.create(ImageUploadApi::class.java) api.uploadImage(googleAuthToken, imagePart).enqueue(object : Callback<ImageResponse> { override fun onResponse(call: Call<ImageResponse>, response: Response<ImageResponse>) { if (response.isSuccessful) { // 上传成功后的逻辑,比如更新本地UI } else { // 上传失败处理,提示用户 } } override fun onFailure(call: Call<ImageResponse>, t: Throwable) { // 网络错误处理 } })
关键注意事项
- 认证适配:确保你的Django后端能正确解析谷歌登录的token,将请求关联到对应的
krisi_user。如果之前的谷歌登录API已经实现了用户关联,request.user就能自动获取当前用户。 - 图片验证:可以在
UserImageSerializer中添加格式、大小验证,比如限制5MB以内,只支持JPG/PNG/WebP:def validate_image(self, value): if value.size > 5 * 1024 * 1024: raise serializers.ValidationError("图片大小不能超过5MB") allowed_formats = ['image/jpeg', 'image/png', 'image/webp'] if value.content_type not in allowed_formats: raise serializers.ValidationError("仅支持JPG、PNG、WebP格式的图片") return value - 生产环境优化:生产环境不要用Django自带的媒体服务,建议搭配云存储(如阿里云OSS、AWS S3)和CDN,提升访问速度和稳定性。
内容的提问来源于stack exchange,提问作者user5908032
相关产品推荐
相关产品推荐

