웹사이트나 앱에서 사용자의 눈에 보이지 않는 곳에서 데이터를 처리하고 시스템을 작동시키는 서버, 데이터 베이스 등 프로그램 뒤를 관리하는 영역이다.
프론트엔드와 백엔드 구조를 가진다.
백엔드 개발에 많이 쓰이는 파이썬 프레임 워크이다.
간단한 문법과 가벼운 실행이 특징이다.
파이썬으로 작성되어 가볍고 유연하다.
초고속 파이썬 패키지 및 프로젝트 관리자이다.
rust로 만들어서 굉장히 빠르다.
pip 설치 기능을 가지고 있다.
버전 관리가 쉽게 되있어 가상 환경을 만들 때 프로젝트마다 환경 부담이 줄어든다.
rust란
메모리 안전성과 뛰어난 성능을 동시에 제공하는 시스템 프로그래밍 언어이다.
@app.route("/경로", methods=["..."]
def xx():
/ 경로에 methods 안에 있는 메서드로 들어왔을 때 xx 함수를 실행한다.
웹 브라우저(클라이언트)가 서버로 보낸 모든 요쳥 정보를 담고 있는 전역 객체이다.
클라이언트가 어떻게 요청을 보냈고 뭘 보냈는지 다 알 수 있다.
name = request.args.get("name","pca")
render_template("이름.html")
현재 경로에 있는 templates/이름.html을 반환한다.
html 안에 flask에 변수, 조건문, 반복문 등을 사용할 수 있게 하는 도구
{{변수}}
{{% 로직 $}}
session["key"] = "value" (value에 딕셔너리, 문자열 사용가능)
from flask import Flask, render_template, request, session
app = Flask(__name__)
app.secret_key = '1234' # Replace with a secure secret key
users = {}
@app.route("/register", methods={"GET", "POST"})
def register():
if request.method == 'post':
username = request.form['username']
password = request.form['password']
if username in users:
return "user already exisists"
users[username] = password
return "register sucessfull"
return render_template('register.html')
@app.route("/login", methods=['GET', 'POST'])
def login():
if request.method == 'post':
username = request.form['username']
password = request.form['password']
if username in users[username] == password:
return "login succsessfull"
session['username'] = username
else:
return "fail"
return render_template('login.html')
if __name__ == "__main__":
app.run(port=5555, debug=True)
```
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Register</title>
</head>
<body>
<form action="/register" method="post">
<input type="text" name="username" placeholder="Username">
<input type="password" name="password" placeholder="Password">
<button type="submit">Register</button>
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>web</title>
</head>
<body>
<form action="/login" method="post">
<input type="text" name="username" placeholder="Username">
<input type="password" name="password" placeholder="Password">
<button type="submit">Login</button>
</form>
</body>
</html>
여러 사람에 의해 공유되어 사용될 목적으로 통합하여 관리되는 데이터의 집합을 말한다. - 데이터 집합소
데이터 베이스를 사용하는 이유는 서버를 끄면 데이터가 다 날라가기 때문에 데이터 베이스를 사용한다.
데이터 베이스는 서버를 꺼도 데이터가 데이터 베이스에 남아있기 때문에 데이터가 날라가지 않는다.
행과 열
회원의 이름(열), 나이(열), 성별(열)을 저장할 때 하나의 결과 (행)로 저장하는 과정
즉, 행은 가로방향의 개별 데이터 단위로, 하나의 객체나 사람에 대한 모든 정보를 담는다.
열은 세로 방향의 속성 단위로 이름, 나이, 성별 등 공통된 데이터 종류를 나타낸다.
경량화된 데이터베이스이다.
서버가 없기 때문에 따로 db서버를 열어둘 필요가 없다.
단일 파일로 로컬에 파일로 저장할 수 있다.
문법이 쉽고 간편하다.
flask와 잘 어울린다.
즉, 별도의 서버 없잉 파일 하나로 가볍게 작동하는 초경량 관계형 데이터 베이스(RDBMS)이다.
스마트폰, 앱, 웹 등에서 널리 사용된다.
CREATE TABLE 테이블 이름 ( 열이름1 데이터 타입, 열이름2 데이터 타입);
이미 이름이 같은 테이블이 있으면 오류 대신 무시한다.
예시코드
CREATE TABLE my_table (
pansy TEXT,
"17" INTEGER
);
모든 열 조회
SELECT * FROM my_table;
특정 열만 조회
SELECT pansy FROM my_table;
문자열 조건 검색(pansy 열의 값이 'flower
인 데이터)SELECT * FROM my_table WHERE pansy = 'flower`;
이 외에도 숫자 조건 (<,>, <=, >=, ==), 다중 조건(AND,OR) 등을 사용할 수 있다.
모든 열에 값을 순서대로 넣을 때 사용한다.
문자열 데이터는 (' ')로 감싸야 한다.
INSERT INTO my_table VALUES ('pansy', 17)
이 외에도 열 이름을 지정하여 삽입하거나 특정 열에만 데이터 삽입도 가능하다.
원하는 데이터만 골라서 수정하려면 WHERE을 함께 사용해야한다.
WHERE를 생략하면 테이블의 모든 행이 변경되므로 주의해야 한다.
UPDATE my_table
SET "17" = 30
WHERE pansy = 'violet';이 외에도 여러 열을 동시에 업데이트 할 수도 있고 전체 데이터를 수정할 수도 있다.
### 데이터 삭제 명령어
데이터를 수정할 때와 마찬 가지로, 특정 데이터만 삭제하려면 `WHERE`을 함께 사용해야 한다.
- pansy 열의 값이 `rose`인 행만 골라서 삭제
``` py
DELETE FROM my_table
WHERE pansy = 'rose';
이 외에도 여러 조건을 만족하는 데이터 삭제, 테이블의 모든 데이터 삭제가 가능하다.
import sqlite3
from flask import Flask, render_template, request, session
app = Flask(__name__)
app.secret_key = '1234'
users = {}
@app.route("/register", methods={"GET", "POST"})
def register():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
if username in users:
return "user already exisists"
users[username] = password
return "register sucessfull"
return render_template('register.html')
@app.route("/login", methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
if username in users and users[username] == password:
session['username'] = username
return "로그인 성공"
return "fail"
return render_template('login.html')
@app.route("/write", methods=["GET", "POST"])
def write():
if request.method == "POST":
title = request.form["title"]
content = request.form["content"]
db = sqlite3.connect("write.db")
db. execute(
"INSERT INTO posts (title, content) VALUES (?, ?)",
(title, content)
)
db.commit()
db.close()
return "작성 완료"
return render_template("write.html")
@app.route("/posts")
def posts():
db = sqlite3.connect("write.db")
posts = db.execute(
"SELECT * FROM posts"
).fetchall()
db.close()
return render_template("posts.html", posts=posts)
@app.route("/edit/<int:id>", methods=["GET", "POST"])
def edit(id):
db = sqlite3.connect("write.db")
if request.method == "POST":
title = request.form["title"]
content = request.form["content"]
db.execute(
"UPDATE posts SET title = ?, content = ? WHERE id = ?",
(title, content, id)
)
db.commit()
db.close()
return "수정 완료"
post = db.execute(
"SELECT * FROM posts WHERE id = ?",
(id,)
).fetchone()
db.close()
return render_template("edit.html", post=post)
@app.route("/delete/<int:id>", methods = ["POST"])
def delete(id):
db = sqlite3.connect("write.db")
db.execute(
"DELETE FROM posts WHERE id = ?",
(id,)
)
db.commit()
db.close()
return "삭제 완료"
@app.route("/search")
def search():
keyword = request.args.get("keyword", "")
db = sqlite3.connect("write.db")
posts = db.execute(
"SELECT * FROM posts WHERE title LIKE ?",
('%' + keyword + '%',)
).fetchall()
db.close()
return render_template("search.html", posts=posts)
@app.route("/")
def index():
db = sqlite3.connect("write.db")
posts = db.execute(
"SELECT * FROM posts"
).fetchall()
db.close()
return render_template("index.html", posts=posts)
if __name__ == "__main__":
app.run(port=5555, debug=True)
CREATE TABLE IF NOT EXISTS posts(
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
content TEXT
);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Board</title>
</head>
<body>
<h2>회원가입</h2>
<form action="/register" method="post">
<input type="text" name="username" placeholder="Username" required>
<input type="password" name="password" placeholder="Password" required>
<button type="submit">회원가입</button>
</form>
<h2>로그인</h2>
<form action="/login" method="post">
<input type="text" name="username" placeholder="Username" required>
<input type="password" name="password" placeholder="Password" required>
<button type="submit">로그인</button>
</form>
<h1>게시판</h1>
<a href="/write">글쓰기</a>
<form action="/search" method="get">
<input type="text" name="keyword" placeholder="검색어" required>
<button type="submit">검색</button>
</form>
{% for post in posts %}
<p>번호: {{ post[0] }}</p>
<p>제목: {{ post[1] }}</p>
<p>내용: {{ post[2] }}</p>
<a href="/edit/{{ post[0] }}">수정</a>
<form action="/delete/{{ post[0] }}" method="post">
<button type="submit">삭제</button>
</form>
<hr>
{% endfor %}
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>web</title>
</head>
<body>
<form action="/login" method="post">
<input type="text" name="username" placeholder="Username">
<input type="password" name="password" placeholder="Password">
<button type="submit">Login</button>
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Register</title>
</head>
<body>
<form action="/register" method="post">
<input type="text" name="username" placeholder="Username">
<input type="password" name="password" placeholder="Password">
<button type="submit">Register</button>
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Write</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<form action="/write" method="post">
<input type="text" name="title" placeholder="Title">
<input type="text" name="content" placeholder="Content" required>
<button type="submit">게시글 작성</button>
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>글 조회</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
{% for post in posts %}
<p>{{ post [0] }}</p>
<p>{{ post [1] }}</p>
<p>{{ post [2] }}</p>
<a href="/edit/{{ post[0] }}">수정</a>
<form action="/delete/{{ post[0] }}" method="post">
<button type="submit">삭제</button>
</form>
<hr>
{% endfor %}
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Edit</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<form action="/edit/{{ post[0] }}" method="post">
<input type="text" name="title" value="{{ post[1] }}" required>
<textarea name="content" required>{{ post[2] }}</textarea>
<button type="submit">게시글 수정</button>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Search</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<form action="/search" method="get">
<input type="text" name="keyword" placeholder="검색어" required>
<button type="submit">검색</button>
</form>
{% for post in posts %}
<P>{{ post[0] }}</P>
<P>{{ post[1] }}</P>
<P>{{ post[2] }}</P>
<hr>
{% endfor %}
</body>
</html>
