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

如何使用graphene-django v2.0上传下载文件?求相关示例

Graphene-Django v2.0 图片上传与下载完整示例

我当年刚上手graphene-django v2.0时,也在文件上传下载这块卡了好久,特意整理了能直接跑通的示例,你跟着一步步来就行:


一、图片下载查询实现

首先得有个存储图片的Django模型,然后把它映射成GraphQL类型,再写查询字段。

1. 定义Django模型

在你的app的models.py里:

from django.db import models

class ImageModel(models.Model):
    title = models.CharField(max_length=100)
    image = models.ImageField(upload_to='uploads/images/')  # 图片会存在MEDIA_ROOT/uploads/images/下
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

2. 创建GraphQL类型

在schema.py里定义对应的ObjectType:

import graphene
from graphene_django import DjangoObjectType
from .models import ImageModel

class ImageType(DjangoObjectType):
    class Meta:
        model = ImageModel
        fields = ("id", "title", "image", "created_at")  # image字段会自动返回相对访问URL

    # 若需要自定义完整绝对URL,可额外添加字段
    image_url = graphene.String()
    def resolve_image_url(self, info):
        # 拼接带域名的完整访问链接
        return info.context.build_absolute_uri(self.image.url)

3. 添加查询字段

在根查询里添加获取图片的字段:

class Query(graphene.ObjectType):
    all_images = graphene.List(ImageType)
    image_by_id = graphene.Field(ImageType, id=graphene.Int(required=True))

    def resolve_all_images(self, info, **kwargs):
        return ImageModel.objects.all()

    def resolve_image_by_id(self, info, id):
        try:
            return ImageModel.objects.get(id=id)
        except ImageModel.DoesNotExist:
            return None

schema = graphene.Schema(query=Query)

4. 查询使用示例

在GraphQL Playground里执行查询:

query {
  allImages {
    id
    title
    image  # 返回相对URL
    imageUrl  # 返回完整绝对URL
    createdAt
  }

  imageById(id: 1) {
    title
    imageUrl
  }
}

二、图片上传突变实现

graphene-django v2.0的文件上传需要用到Upload类型,还要确保Django的媒体配置正确。

1. 先配置Django媒体设置

在settings.py里添加:

import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

然后在项目的urls.py里添加媒体路由:

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # 你的其他路由
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

2. 定义上传突变

在schema.py里添加:

class UploadImageMutation(graphene.Mutation):
    class Arguments:
        title = graphene.String(required=True)
        image = graphene.Upload(required=True)  # 用Upload类型接收文件

    # 突变返回的结果类型
    image = graphene.Field(ImageType)

    def mutate(self, info, title, image):
        # 处理上传文件,创建ImageModel实例
        image_instance = ImageModel(
            title=title,
            image=image  # 直接把Upload对象赋值给ImageField
        )
        image_instance.save()
        return UploadImageMutation(image=image_instance)

# 根突变类
class Mutation(graphene.ObjectType):
    upload_image = UploadImageMutation.Field()

# 更新schema,包含突变
schema = graphene.Schema(query=Query, mutation=Mutation)

3. 上传使用示例

方式1:用GraphQL Playground上传

在Playground里选择Mutation,然后用文件选择器上传:

mutation($title: String!, $image: Upload!) {
  uploadImage(title: $title, image: $image) {
    image {
      id
      title
      imageUrl
    }
  }
}

在Variables里填写:

{
  "title": "我的测试图片"
}

再在下方的“Map”区域把$image映射到你选择的本地图片文件。

方式2:用curl命令上传

curl -X POST \
  http://localhost:8000/graphql/ \
  -F operations='{"query": "mutation($title: String!, $image: Upload!) { uploadImage(title: $title, image: $image) { image { id title imageUrl } } }", "variables": {"title": "测试图片", "image": null}}' \
  -F map='{"0": ["variables.image"]}' \
  -F 0=@/path/to/your/image.jpg

几个关键注意事项

  • 确保安装了pillow库(Django处理图片依赖它):pip install pillow
  • 生产环境不要用static路由,要用Nginx等服务器处理媒体文件访问
  • 如果遇到权限问题,检查MEDIA_ROOT目录的读写权限

内容的提问来源于stack exchange,提问作者sgaseretto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:15:02