Flutter 如何将照片上传到 REST API
Flutter how to upload a photo to 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')
我做了一些研究,发现因为只有经过身份验证的用户才能 post 图像,所以我需要以某种方式使用用户在登录时收到的令牌。
我在登录时获得了用户令牌,并且能够使用配置单元将其保存在本地。但是我不知道下一步该怎么做。
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;
}
这是我的登录代码,它是 returns json 格式,包含用户名、user_id 和令牌。像这样:
{
"token": "dc9e0de8fa2eaa917657e810db06aad2458e4f65",
"user_id": 4,
"username": "maria"
}
您可能想要做的是在请求中传递令牌 header。这样的事情应该有效:
static Future<dynamic> loginUser(String username, String password) async {
final response = await http.post(
"$apiURL/en/api/users/login/",
body: {
"username": username,
"password": password,
},
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Token $token',
},
);
return response?.body;
}
请注意,headers 包含一个名为 Authorization 的字段,这是您传递令牌的地方。包含令牌的字符串中的关键字 Token
指定您正在使用的身份验证类型。如果不行,可能是你使用了另一种授权方式。
我建议你看看https://www.django-rest-framework.org/api-guide/authentication/
合并我在评论中给出的建议。
编写此代码以同时添加 headers 身份验证令牌和文件:
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);
});
}
我需要将带有标题和用户名的图像上传到使用 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')
我做了一些研究,发现因为只有经过身份验证的用户才能 post 图像,所以我需要以某种方式使用用户在登录时收到的令牌。
我在登录时获得了用户令牌,并且能够使用配置单元将其保存在本地。但是我不知道下一步该怎么做。
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;
}
这是我的登录代码,它是 returns json 格式,包含用户名、user_id 和令牌。像这样:
{
"token": "dc9e0de8fa2eaa917657e810db06aad2458e4f65",
"user_id": 4,
"username": "maria"
}
您可能想要做的是在请求中传递令牌 header。这样的事情应该有效:
static Future<dynamic> loginUser(String username, String password) async {
final response = await http.post(
"$apiURL/en/api/users/login/",
body: {
"username": username,
"password": password,
},
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Token $token',
},
);
return response?.body;
}
请注意,headers 包含一个名为 Authorization 的字段,这是您传递令牌的地方。包含令牌的字符串中的关键字 Token
指定您正在使用的身份验证类型。如果不行,可能是你使用了另一种授权方式。
我建议你看看https://www.django-rest-framework.org/api-guide/authentication/
合并我在评论中给出的建议。
编写此代码以同时添加 headers 身份验证令牌和文件:
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);
});
}