首页 > 解决方案 > Flutter 如何将照片上传到 REST API

问题描述

我需要将带有标题和用户名的图像上传到使用 Django 构建的 API。在 Django 中创建 Post 视图标有@permission_classes((IsAuthenticated,))。这是代码:

@permission_classes((IsAuthenticated,))
class PostCreateAPIView(CreateAPIView):
    serializer_class = PostSerializer

    def get_queryset(self):
        return Post.objects.all()

序列化器:

class PostSerializer(ModelSerializer):
    class Meta:
        model = Post
        fields = ('author', 'description', 'image', 'created_at')

我做了一些研究,发现由于只有经过身份验证的用户才能发布图像,我需要以某种方式使用用户在登录时收到的令牌。

我在登录时获得了用户令牌,并且能够使用 hive 将其保存在本地。但是我不知道下一步该做什么。

static Future<dynamic> loginUser(String username, String password) async {
    final response = await http.post("$apiURL/en/api/users/login/", body: {
      "username": username,
      "password": password,
    });

    return response?.body;
  }

这是我的登录代码,它返回带有用户名、user_id 和令牌的 json 格式。像这样:

{
    "token": "dc9e0de8fa2eaa917657e810db06aad2458e4f65",
    "user_id": 4,
    "username": "maria"
}

标签: flutterdjango-rest-frameworkhttp-post

解决方案


合并我在评论中给出的建议。

编写此代码以同时添加带有身份验证令牌和文件的标头:

upload(File imageFile, String token) async {    
      // open a bytestream
      var stream = new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
      // get file length
      var length = await imageFile.length();

      // string to uri
      var uri = Uri.parse("http://ip:8082/composer/predict");

      // create multipart request
      var request = new http.MultipartRequest("POST", uri);

      // add headers with Auth token
      Map<String, String> headers = { "Authorization": "Token $token"};

      request.headers.addAll(headers);

      // multipart that takes file
      var multipartFile = new http.MultipartFile('file', stream, length,
          filename: basename(imageFile.path));

      // add file to multipart
      request.files.add(multipartFile);

      // send
      var response = await request.send();
      print(response.statusCode);

      // listen for response
      response.stream.transform(utf8.decoder).listen((value) {
        print(value);
      });
    }

推荐阅读