#15. ๋งํฌ์๋น์ค ๊ด๋ฆฌ์ํ๋ฉด ๋ฐ ๋งํฌ๋ฆฌ์คํธ ํธ์ง
์ฐ์ ๋งํฌ์ ๋ณด๋ฅผ ํธ์งํ๋ฉด์ ๋งํฌ์ ๋ณด๋ฅผ ์ญ์ ์ฒ๋ฆฌ์ ์ด๋ฏธ ๋ฑ๋ก๋ ์ด๋ฏธ์ง๋ฅผ ์ญ์ ํ๋ ๋ฐฑ์๋๋ฅผ ์ ์ํ์
โ links.py ( ์์น: linkservice/server/src/links.py)
---------------------------------------------------------------------------------------------------
Python๋ฐฑ์๋ links.py์ LinkRemove(Resource) ์ ์์ ํ๋ค.
๊ด๋ จ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ import ํ๋ค. ( current_app, os )
from flask import jsonify, request, current_app
import os
"""
DELETE /api/link/delete/<int:id> - ๋งํฌ์ ๋ณด์ญ์
"""
class LinkRemove(Resource):
def delete(self, id):
# id์ ํด๋น๋๋ ๋งํฌ ์ ๋ณด ์กฐํ
link_data = LinkModel.find_by_id(id)
folder = current_app.config.get('IMAGE_FORDER')
# ์ด๋ฏธ์ง ๋งํฌ ํญ๋ชฉ ๊ฐ์ ธ์ค๊ธฐ
if link_data.imageurl is not None:
imageurl = link_data.imageurl.split('/')
file_name = imageurl[len(imageurl) - 1]
#ํ์ผ ์กด์ฌ์ฌ๋ถ ํ์ธํ ์ด๋ฏธ์ง ํ์ผ์ ์ญ์ ํ๋ค.
if os.path.isfile(folder + file_name):
os.remove(folder + file_name)
# ์ ๋ณด ์ญ์ ( links_model์ delete_by_id ๋ฉ์๋ ํธ์ถ )
LinkModel.delete_by_id(id)
return {'message':'์ ์์ ์ผ๋ก ์ญ์ ๋์์ต๋๋ค.'},201
โโ๋งํฌ์ ๋ณด๋ฅผ ํธ์งํ๋ ํ๋ฉด ์ ์
โ links.edit.jsx ( ์์น: linkservice/client/src/component/links.edit.jsx )
-------------------------------------------------------------------------------------------------
links.edit.jsx๋ ๋งํฌ ์ ๋ณด๋ฅผ ํธ์ง ํ๋ ํ๋ฉด์ด๋ค.
ํ๋ฉด ๊ตฌ์ฑ๊ณผ ์ด๋ฒคํธ ํธ๋ค๋ฌ ํจ์๋ค์ ๋ชจ๋ ์ ๊ท ๋ฑ๋ก(links.create.jsx) ๊ณผ ๋์ผํ๋ฉฐ,
๋จ useEffect์์ ํธ์งํ๊ณ ์ ํ๋ ๋งํฌ์ ๋ณด์ id ๊ฐ์ ๋ฐ์ ์ถ๋ ฅํ๋ ๋ถ๋ถ๊ณผ handleSubmit์ ์ ๋ฐ์ดํธํ๋
์๋น์ค๋ฅผ ์ถ๊ฐ ํ๋ฉด ๋๋ค.
import React, { useState, useEffect } from "react"
import { useParams, useNavigate } from "react-router-dom"
import linkService from "./service/service";
import {useDropzone} from 'react-dropzone'
export default function LinkEdit () {
//id๊ฐ์ ๋ฐ์์ค๊ธฐ ์ํด์ react์์ ์ ๊ณตํ useParams์ ํ์ฉํ๋ค.
let params = useParams()
const [data, setData] = useState({})
const [values, setValues] = useState({})
const [image, setImage] = useState(null)
const [preview, setPreview] = useState('/assets/default.jpg')
const navigate = useNavigate();
useEffect(() => {
linkService.getSelectLink(params.id).then(
(res)=> {
setData(res.data)
// ์์ ์๋น์ค์ธ linkService.updateLink ์ ๋๊ฒจ์ฃผ๊ธฐ ์ํ values
setValues(res.data.links)
// preview์ ์ํ setProview๊ฐ
setPreview(res.data.links.imageurl)
}, (error) => {
alert(error.res.data.message )
}
)
// eslint-disable-next-line
}, [params.id])
// Drag & Drap ๊ด๋ จ ์คํ function
function onDrop(acceptedFiles) {
const reader = new FileReader();
const file = acceptedFiles
if (file) {
reader.readAsDataURL(file[0]);
setImage(file[0]);
}
reader.onload = (e) => {
setPreview(reader.result);
setValues((prevValues) => ({
...prevValues,
[`imageurl`]: file[0].name,
}))
document.getElementsByName("imageurl")[0].value = ''
};
}
const handleChange = async (e) => {
const nextValues = {
...values,
[e.target.name]: e.target.value
}
setValues(nextValues)
// ์ฌ์ง๋งํฌ์ ๋ณด ์
๋ ฅ์ preview๋ฅผ ์ํ set
if (e.target.name === 'imagelink') {
setPreview(e.target.value)
}
}
const handleSubmit = async (e) => {
e.preventDefault();
const formData = new FormData();
linkService.updateLink(params.id, values).then(
(res)=> {
// image file์ ์ ํ์ ์ด๋ฏธ์ง ์
๋ก๋๋ฅผ ์ํด์ ์งํ
if (image) {
formData.append('image', image)
linkService.changeImage(formData, params.id).then(
(res)=> {
// console.log(res)
}
)
}
alert(res.data.message)
navigate("/links/list", { replace: true})
}, (error) => {
alert(error.res.data.message )
}
)
}
// Drag & Drop์ ์ํ ๊ธฐ์กด const ์ ์ธ
const {getRootProps, getInputProps} = useDropzone({onDrop})
return (
<div>
{(typeof data.links ==='undefined') ? (
<p>Loading....</p>
) : (
<>
<div className="title-container">
<h1 className="text-title">๋งํฌ ์์ </h1>
</div>
<form onSubmit={handleSubmit}>
<div className="input-wrap">
<label>๋งํฌ๋ช
</label>
<div className="input-box">
<input type="text" name="name"
defaultValue={data.links.name}
className="input-css"
onChange={handleChange}
autoFocus="autofocus"
/>
</div>
</div>
<div className="input-wrap">
<label>ํ๊ทธ ์ ๋ณด ( ํ๊ทธ์ฌ๋ฌ๊ฐ ๋ฑ๋ก์ / ๋ก ๊ตฌ๋ถ )</label>
<div className="input-box">
<input type="text" name="tag"
defaultValue={data.links.tag}
className="input-css"
onChange={handleChange}
/>
</div>
</div>
<div className="input-wrap">
<label>๋งํฌ URL (์ฐ๊ฒฐํ๊ณ ์ ํ๋ URL)</label>
<div className="input-box">
<input type="text" name="linkurl"
defaultValue={data.links.linkurl}
className="input-css"
onChange={handleChange}
/>
</div>
</div>
<div className="input-wrap">
<label>์ฌ์ง ๋งํฌ ์ ๋ณด</label>
<div className="input-box">
<input type="text" name="imageurl"
defaultValue={data.links.imageurl}
className="input-css"
onChange={handleChange}
/>
</div>
</div>
<div className="img_contain" >
<div className="img_wrap" {...getRootProps()} >
<img src = { preview }
alt='์ด๋ฏธ์ง' className="img_box" />
<input {...getInputProps()} multiple={false} name='imageurl'/>
</div>
<div className="text_type">
<span>์ฌ์ง ๋งํฌ ์ ๋ณด๋ฅผ ๋ฑ๋กํ๊ฑฐ๋ <br></br>
์ด๋ฏธ์ง๋ฅผ ์ง์ ๋์ด์ค๊ฑฐ๋<br></br>
ํ์ผ์ ์ ํํด์ฃผ์ธ์</span>
</div>
</div>
<div>
<button type="submit" className="btn btn-primary">์ ์ </button>
</div>
</form>
</>
)}
</div>
)
}
๋งํฌ์ ๋ณด์ ๋ํ ๋ฑ๋ก/์์ /์ญ์ ๊ฐ ๋ชจ๋ ๋๋ฌ๋ค.
๋ค์ํธ์๋ ๋ง๋ค์ด์ง ์์ค๋ก ์ข๋ ํ์ํ ์ฌ๋ฌ๊ฐ์ง ๊ธฐ๋ฅ๊ณผ ๋ํ ์ผํ ์์ ์ ์งํํด ๋ณด์.
'React&Python์ผ๋ก ์น๊ฐ๋ฐ > ๋งํฌ์๋น์ค' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
#17. ๋งํฌ์๋น์ค ํ๋ก์ ํธ ์ ๋ฆฌ(git ์ฃผ์) (0) | 2023.05.02 |
---|---|
#15. ๋งํฌ์๋น์ค ๊ด๋ฆฌ์ํ๋ฉด ๋ฐ ๋งํฌ๋ฆฌ์คํธ ํธ์ง (0) | 2023.04.29 |
#14. material-icons ๋ฅผ ํตํ ๋ฉ๋ดํ๋ฉด (0) | 2023.04.29 |
#13. ๋ฑ๋กํ๋ฉด์์ ๋ด์ฉ ์ ์ฅ ๋ฐ ์ด๋ฏธ์ง ์ ์ฅ ๊ธฐ๋ฅ ๊ตฌํ (0) | 2023.04.15 |
#12. React์์ Drag & Drop์ ์ด์ฉํ ์ด๋ฏธ์ง ์ ๋ก๋ (0) | 2023.04.12 |