将个人资料图片从反应前端发送到 flask-restful 后端并存储
Sending a profile picture from react frontend to flask-restful backend and storing
我想将个人资料图片存储在文件系统 (images/{username}_pfp.{extension} 并将其位置作为字符串存储在数据库中。
我的前端反应代码是
const Signup = () => {
const [state, setState] = useState({
email: "",
password: "",
confirmPassword: "",
username: "",
profile_picture: "",
});
const navigate = useNavigate();
const onSubmit = (e) => {
e.preventDefault();
console.log(state.email, state.password, state.confirmPassword, state.username);
if (state.password === state.confirmPassword) {
getData('http://localhost:5000/users')
.then(data => {
console.log(data);
let userExists = false;
for (let i = 0; i < data.length; i++) {
if (data[i].email === state.email) {
userExists = true;
}
if (data[i].username === state.username) {
userExists = true;
}
}
if (userExists) {
alert("Email or Username already exists");
} else {
const data = new FormData();
for(var x = 0; x<state.profile_picture.length; x++) {
data.append('file', state.profile_picture[x])
}
postData('http://localhost:5000/users', {
email: state.email,
password: state.password,
name: state.username,
profile_picture: data
})
.then(data => {
console.log(data);
alert("User created successfully");
navigate('/');
})
.catch(err => {
console.log(err);
alert("Error creating user");
});
}
})
.catch(err => {
console.log(err);
alert("Error creating user");
});
};
};
return (
<>
<Header />
<div className="container">
<Form>
//creating other values
<Form.Group className="mb-3" controlId="formFile">
<Form.Label>Upload Profile Picture (image format must be png, jpg, or jpeg).</Form.Label>
<Form.Control type="file" onChange={e => setState(prevState => { return {...prevState, profile_picture: e.target.value}})}/>
</Form.Group>
<Button variant="primary" type="submit" onClick={onSubmit}>
Submit
</Button>
</Form>
</div>
</>
);
};
我的 Flask 后端代码是
class UserListResource(Resource):
def get(self):
users = User.query.all()
return users_schema.dump(users)
def post(self):
received_file = request.json['profile_picture']
filename = request.json['name'] + '_pfp' + received_file.filename.split('.')[1]
filename = secure_filename(filename)
filename = os.path.join(app.config['UPLOAD_FOLDER'], filename)
received_file.save(filename)
new_user = User(
email=request.json['email'],
password=request.json['password'],
name=request.json['name'],
profile_picture=filename
)
db.session.add(new_user)
db.session.commit()
return user_schema.dump(new_user)
api.add_resource(UserListResource, '/users')
我从多个来源 (, https://flask.palletsprojects.com/en/2.1.x/patterns/fileuploads/) 获得了与此相关的代码位。图片发送到后端时,在后端终端报AttributeError: dict object has no attribute filename。我怎样才能让它工作?我错过了什么吗?
所以。我尝试了更多的东西,我想我会回复这个来为其他人记录下来。我的前端代码最终发送了两个单独的 post 请求,一个发送给 post json 数据,另一个发送给图像。
顺便说一句,前端代码使用react-bootstrap,但原理是一样的。
前端代码:
const Signup = () => {
const [state, setState] = useState({
email: "",
password: "",
confirmPassword: "",
username: "",
});
const [profile_picture, setProfile_picture] = useState({});
const navigate = useNavigate();
const uploadedImage = (e) => {
console.log(e.target.files[0]);
const formData = new FormData();
formData.append('profile_picture', e.target.files[0]);
console.log(formData);
setProfile_picture(formData);
};
const onSubmit = (e) => {
e.preventDefault();
console.log(state.email, state.password, state.confirmPassword, state.username);
if (state.password === state.confirmPassword) {
getData('http://localhost:5000/users')
.then(data => {
console.log(data);
let userExists = false;
for (let i = 0; i < data.length; i++) {
if (data[i].email === state.email) {
userExists = true;
}
if (data[i].username === state.username) {
userExists = true;
}
}
if (userExists) {
alert("Email or Username already exists");
} else {
postData('http://localhost:5000/users', {
email: state.email,
password: state.password,
name: state.username,
})
.then(data => {
console.log(data);
alert("User created successfully");
fetch('http://localhost:5000/users/' + data.name, {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
cors: 'cors',
redirect: 'follow',
referrerPolicy: 'no-referrer',
body: profile_picture,
})
.then(response => {
console.log(response);
})
navigate('/');
})
.catch(err => {
console.log(err);
alert("Error creating user in post thing");
});
}
})
.catch(err => {
console.log(err);
alert("Error creating user");
});
};
};
return (
<>
<Header />
<div className="container">
<Form>
<Form.Group className="mb-3" controlId="formBasicEmail">
<Form.Label>Email address</Form.Label>
<Form.Control type="email" placeholder="Enter email" value={state.email} onChange={e => setState(prevState => { return {...prevState, email: e.target.value}})}/>
<Form.Text className="text-muted">
We'll never share your email with anyone else.
</Form.Text>
</Form.Group>
// making more input fields
<Form.Group className="mb-3" controlId="formFile">
<Form.Label>Upload Profile Picture (image format must be png, jpg, or jpeg).</Form.Label>
<Form.Control type="file" onChange={e => uploadedImage(e)}/>
</Form.Group>
<Button variant="primary" type="submit" onClick={onSubmit}>
Submit
</Button>
</Form>
</div>
</>
);
};
图像的后端代码是
def post(self, user_name):
current_user = User.query.get_or_404(user_name)
received_file = request.files['profile_picture']
filename = current_user.name + '_pfp' + '.' + received_file.filename.split('.')[1]
filename = secure_filename(filename)
filename = os.path.join(app.config['UPLOAD_FOLDER'], filename)
img_file = Image.open(received_file.stream)
img_file.save(filename)
current_user.profile_picture = filename
db.session.commit()
return user_schema.dump(current_user)
第一个 post 请求只是将 profile_picture 字段定义为空字符串。当然,在用户删除功能中添加几行删除头像文件:
def delete(self, user_name):
user = User.query.get_or_404(user_name)
pfp_fname = user.profile_picture
os.remove(pfp_fname)
db.session.delete(user)
db.session.commit()
return '', 204
希望这对您有所帮助,如果您需要说明,请随时发表评论 :)。另外,post注释中的数据和 getData 函数,因为它们只是获取请求。
我想将个人资料图片存储在文件系统 (images/{username}_pfp.{extension} 并将其位置作为字符串存储在数据库中。 我的前端反应代码是
const Signup = () => {
const [state, setState] = useState({
email: "",
password: "",
confirmPassword: "",
username: "",
profile_picture: "",
});
const navigate = useNavigate();
const onSubmit = (e) => {
e.preventDefault();
console.log(state.email, state.password, state.confirmPassword, state.username);
if (state.password === state.confirmPassword) {
getData('http://localhost:5000/users')
.then(data => {
console.log(data);
let userExists = false;
for (let i = 0; i < data.length; i++) {
if (data[i].email === state.email) {
userExists = true;
}
if (data[i].username === state.username) {
userExists = true;
}
}
if (userExists) {
alert("Email or Username already exists");
} else {
const data = new FormData();
for(var x = 0; x<state.profile_picture.length; x++) {
data.append('file', state.profile_picture[x])
}
postData('http://localhost:5000/users', {
email: state.email,
password: state.password,
name: state.username,
profile_picture: data
})
.then(data => {
console.log(data);
alert("User created successfully");
navigate('/');
})
.catch(err => {
console.log(err);
alert("Error creating user");
});
}
})
.catch(err => {
console.log(err);
alert("Error creating user");
});
};
};
return (
<>
<Header />
<div className="container">
<Form>
//creating other values
<Form.Group className="mb-3" controlId="formFile">
<Form.Label>Upload Profile Picture (image format must be png, jpg, or jpeg).</Form.Label>
<Form.Control type="file" onChange={e => setState(prevState => { return {...prevState, profile_picture: e.target.value}})}/>
</Form.Group>
<Button variant="primary" type="submit" onClick={onSubmit}>
Submit
</Button>
</Form>
</div>
</>
);
};
我的 Flask 后端代码是
class UserListResource(Resource):
def get(self):
users = User.query.all()
return users_schema.dump(users)
def post(self):
received_file = request.json['profile_picture']
filename = request.json['name'] + '_pfp' + received_file.filename.split('.')[1]
filename = secure_filename(filename)
filename = os.path.join(app.config['UPLOAD_FOLDER'], filename)
received_file.save(filename)
new_user = User(
email=request.json['email'],
password=request.json['password'],
name=request.json['name'],
profile_picture=filename
)
db.session.add(new_user)
db.session.commit()
return user_schema.dump(new_user)
api.add_resource(UserListResource, '/users')
我从多个来源 (
所以。我尝试了更多的东西,我想我会回复这个来为其他人记录下来。我的前端代码最终发送了两个单独的 post 请求,一个发送给 post json 数据,另一个发送给图像。
顺便说一句,前端代码使用react-bootstrap,但原理是一样的。 前端代码:
const Signup = () => {
const [state, setState] = useState({
email: "",
password: "",
confirmPassword: "",
username: "",
});
const [profile_picture, setProfile_picture] = useState({});
const navigate = useNavigate();
const uploadedImage = (e) => {
console.log(e.target.files[0]);
const formData = new FormData();
formData.append('profile_picture', e.target.files[0]);
console.log(formData);
setProfile_picture(formData);
};
const onSubmit = (e) => {
e.preventDefault();
console.log(state.email, state.password, state.confirmPassword, state.username);
if (state.password === state.confirmPassword) {
getData('http://localhost:5000/users')
.then(data => {
console.log(data);
let userExists = false;
for (let i = 0; i < data.length; i++) {
if (data[i].email === state.email) {
userExists = true;
}
if (data[i].username === state.username) {
userExists = true;
}
}
if (userExists) {
alert("Email or Username already exists");
} else {
postData('http://localhost:5000/users', {
email: state.email,
password: state.password,
name: state.username,
})
.then(data => {
console.log(data);
alert("User created successfully");
fetch('http://localhost:5000/users/' + data.name, {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
cors: 'cors',
redirect: 'follow',
referrerPolicy: 'no-referrer',
body: profile_picture,
})
.then(response => {
console.log(response);
})
navigate('/');
})
.catch(err => {
console.log(err);
alert("Error creating user in post thing");
});
}
})
.catch(err => {
console.log(err);
alert("Error creating user");
});
};
};
return (
<>
<Header />
<div className="container">
<Form>
<Form.Group className="mb-3" controlId="formBasicEmail">
<Form.Label>Email address</Form.Label>
<Form.Control type="email" placeholder="Enter email" value={state.email} onChange={e => setState(prevState => { return {...prevState, email: e.target.value}})}/>
<Form.Text className="text-muted">
We'll never share your email with anyone else.
</Form.Text>
</Form.Group>
// making more input fields
<Form.Group className="mb-3" controlId="formFile">
<Form.Label>Upload Profile Picture (image format must be png, jpg, or jpeg).</Form.Label>
<Form.Control type="file" onChange={e => uploadedImage(e)}/>
</Form.Group>
<Button variant="primary" type="submit" onClick={onSubmit}>
Submit
</Button>
</Form>
</div>
</>
);
};
图像的后端代码是
def post(self, user_name):
current_user = User.query.get_or_404(user_name)
received_file = request.files['profile_picture']
filename = current_user.name + '_pfp' + '.' + received_file.filename.split('.')[1]
filename = secure_filename(filename)
filename = os.path.join(app.config['UPLOAD_FOLDER'], filename)
img_file = Image.open(received_file.stream)
img_file.save(filename)
current_user.profile_picture = filename
db.session.commit()
return user_schema.dump(current_user)
第一个 post 请求只是将 profile_picture 字段定义为空字符串。当然,在用户删除功能中添加几行删除头像文件:
def delete(self, user_name):
user = User.query.get_or_404(user_name)
pfp_fname = user.profile_picture
os.remove(pfp_fname)
db.session.delete(user)
db.session.commit()
return '', 204
希望这对您有所帮助,如果您需要说明,请随时发表评论 :)。另外,post注释中的数据和 getData 函数,因为它们只是获取请求。