Django
The web framework for perfectionists with deadlines.
www.djangoproject.com
URL
URL 패턴 분리
- URL 구성을 체계적이고 관리하기 쉽게 만들어 주기 위함.
- mysite/urls.py
from django.urls import path, include
# from articles import views
urlpatterns = [
path("admin/", admin.site.urls),
# path("articles/", views.data),
# path("articles/json-data/", views.json_data),
path("articles/", include("articles.urls")),
]
- articles/urls.py
from django.urls import path
from articles import views
urlpatterns = [
path("", views.data),
path("json-data/", views.json_data),
]
Path Parameter
- URL에 포함된 문자열을 뷰(views.py)에서 변수로 활용할 수 있다.
- articles/urls.py
urlpatterns = [
path("", views.data),
path("json-data/", views.json_data),
path("random-data/<int:num>/", views.random_data),
]
- articles/views.py
import random
def random_data(request, num):
data = []
for _ in range(num):
data.append(sorted(random.sample(range(1, 45), 6)))
return JsonResponse(data, safe=False)
[response]
Django Model
- dababase의 스키마를 지정한다.
- django가 만들어 둔 Model class를 상속받아 사용한다.
- 하나의 Model class는 하나의 table과 매핑된다.
- 각 필드(column)에 저장될 데이터 타입을 명시해야 한다.
- articles/models.py
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
def __str__(self):
return f"{self.id}: {self.title}"
- CharField : 길이의 제한이 있는 문자열 필드
- TextField : 길이의 제한이 없는 문자열 필드
migration
- makemigrations
- models.py를 작성하면서 생긴 model의 변경사항을 기록한다.
- app_name/migrations/ 폴더에 변경사항이 기록된 파일이 생성된다.
$ python manage.py makemigrations
- migrate
- makemigrations을 통해 기록된 변경사항을 database에 반영한다.
- db.sqlite3 라는 database에 table이 생성된다.
$ python manage.py migrate
sqlite
- vscode extension SQLite 설치
- db.sqlite3 우클릭 → Open Database
- 하단의 SQLITE EXPLORER 생성 및 DB 확인
Model 수정
articles/models.py
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return f"{self.id}: {self.title}"
- makemigrations
$ python manage.py makemigrations
It is impossivle to add the field 'created_at' with 'auto_now_add=True' to article without providing a default.
this is because the database needs something to populate existing rows.
1) Provide a one-off default now which will be set on all existing rows
2) Quit and manually define a default value in models.py
Select an option: []
→ 1 + enter
→ enter
- table에 필드가 추가되었으므로, 그들의 값을 지정하라는 내용
- migrate
ORM
- ORM(Object-Relational Mapping)은 객체 지향 프로그래밍 언어를 사용하여 호환되지 않는 유형의 시스템 간에 데이터를 변환하는 프로그래밍 기술
- 즉, 데이터베이스의 테이블을 객체로 매핑해서, SQL을 직접 쓰지 않고도 데이터베이스를 조작할 수 있게 해준다.
- 데이터베이스의 데이터를 객체로 추상화하여 사용할 수 있게 되므로, 개발자는 객체 지향적인 방식으로 데이터베이스를 다룰 수 있습니다.
- 장점
- 생산성과 속도: SQL 쿼리를 직접 작성하고 최적화하는 데 많은 시간이 소요될 수 있는데, ORM을 사용하면 이러한 작업을 자동화하여 개발 속도를 높일 수 있다.
- 유지보수성: 데이터베이스 로직이 객체와 메소드에 의해 추상화되어 있어, 코드의 가독성과 유지보수성이 향상된다.
- 보안: SQL 쿼리를 직접 작성할 때 발생할 수 있는 SQL 인젝션 같은 보안 취약점을 ORM이 자동으로 처리해 준다.
- 데이터베이스 독립성: ORM을 사용하면 데이터베이스 시스템을 변경하더라도 애플리케이션 코드의 대부분을 그대로 유지할 수 있다. ORM 라이브러리가 데이터베이스 간의 차이를 추상화해 준다.
- RDBMS마다 사용하는 SQL문법이 조금씩 상이하다.
- 단점
- 성능 저하: ORM은 SQL 쿼리를 자동으로 생성하기 때문에, 때로는 수동으로 최적화된 쿼리보다 성능이 떨어질 수 있다.
- 복잡한 쿼리의 어려움: 매우 복잡한 쿼리나 특수한 최적화가 필요한 경우, ORM을 사용하는 것이 직접 쿼리를 작성하는 것보다 어렵거나 비효율적일 수 있다.
SQL 인젝션
- 보안 취약점 중 하나로, 악의적인 사용자가 웹 양식 입력 또는 URL 쿼리 문자열을 통해 SQL 명령어를 데이터베이스 시스템에 주입(인젝션)하여 실행시키는 기법
- SQL 인젝션을 통해 공격자는 데이터베이스에서 민감한 정보를 읽어내거나, 데이터를 변경, 삭제하는 등의 행위를 할 수 있으며, 심지어 데이터베이스 서버를 완전히 제어할 수도 있다.
[ex]
다음과 같은 id, password를 입력받아 로그인하는 프로그램이 있을 때
SELECT * FROM users WHERE username='{$username}' AND password='{$password}'
username에 admin, password에 아무거나 OR 1=1 —를 입력하면
SELECT * FROM users WHERE username='admin' and password='password' OR 1=1 --'
가 되어 1=1은 항상 참이므로 admin계정에 로그인할 수 있게 된다.
Django에서의 ORM
모델이름.objects.명령어()
- objects
- django model이 database에 query를 날릴 수 있게 해주는 인터페이스
- 명령어는 아래의 문서 참고
Django
The web framework for perfectionists with deadlines.
docs.djangoproject.com
Data create, read
create
- articles/urls.py
urlpatterns = [
path("", views.data),
path("json-data/", views.json_data),
path("random-data/<int:num>/", views.random_data),
path("create/", views.create),
]
- articles/views.py
from .models import Article
def create(request):
article = Article(title="test", content="test")
article.save()
return HttpResponse(article)
- response
1: test title
read(전체)
- articles/urls.py
urlpatterns = [
path("", views.data),
path("json-data/", views.json_data),
path("random-data/<int:num>/", views.random_data),
path("create/", views.create),
path("read/", views.read),
]
- articles/views.py
def read(request):
articles = Article.objects.all()
return HttpResponse(articles)
- response
1: test title2: test title
read(하나)
- articles/urls.py
urlpatterns = [
path("", views.data),
path("json-data/", views.json_data),
path("random-data/<int:num>", views.random_data),
path("create", views.create),
path("read", views.read),
path("read/<int:id>", views.read_id),
]
- articles/views.py
def read_id(request, id):
article = Article.objects.get(id=id)
return HttpResponse(article)
- response
2: test title
Data seeding
- 데이터베이스에 초기 세트의 데이터를 사전에 입력하는 과정이다.
- 설치
$ pip install django-seed
- app 추가
INSTALLED_APPS = [
...
'django_seed',
]
- 사용법
$ python manage.py seed {app_name} --number=15
'Django' 카테고리의 다른 글
마이그레이션 : 관련 모델이나 필드가 해석되지 못할 때 (0) | 2024.03.19 |
---|---|
Django : backend framework(5) (0) | 2024.03.19 |
Django : backend framework(4) (0) | 2024.03.18 |
Django : backend framework(3) (0) | 2024.03.15 |
Django : backend framework(1) (0) | 2024.03.14 |