You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:36:18