본문 바로가기

Back-end & Server/Django

[Django] 모델

728x90
반응형

Django의 데이터베이스 사용

일반적으로 응용 프로그램에서 데이터베이스를 사용하는 방법은 쿼리를 하드 코딩하여 사용하는 방법을 사용함

하지만 Django는 이러한 연결 생성, 커서 생성, 명령문 실행 및 닫기 등의 작업을 하드 코딩없이 사용할 수 있음

 

데이터베이스 구성

먼저 setting.py'DATABASE''default'을 살펴보면 다음과 같음(SQLite를 사용)

  • ENGINE : Django에게 사용할 데이터베이스 엔진을 알려줌
  • NAME : Django에 데이터베이스 이름을 알려줌

 

앱(APP)

우리는 앞서 Django 프로젝트를 하나 만들었음 -> mysite

프로젝트

  • 특정 Django 앱 세트의 인스턴스와 해당 앱의 구성
  • 설정 파일을 제공 -> 데이터베이스 연결 정보, 설치된 앱, DIRS 등을 정의

 

앱 

  • 휴대 가능한 Django 기능 세트, 일반적으로 단일 파이썬 패키지에 공존하는 모델 및 뷰를 포함
  • 여러 프로젝트에 이식성이 있음
  • Django의 데이터베이스 모델을 사용하는 경우 Django App을 만들어야 함 -> 앱 규칙 요구 사항

 

새로운 앱 만들기

python manage.py startapp 앱이름

위의 명령어를 터미널에 입력하여 새로운 앱을 만들 수 있음 -> mysite 디렉터리 내에 '앱이름' 디렉터리를 새로 만듦

books 디렉토리는 앱의 모델과 뷰를 포함하고 있음

model.pyviews.py는 Django App을 위한 빈 슬레이트

 

모델 작성

Django와 데이터베이스 레이아웃을 사용하기 위해서는 먼저 데이터베이스를 파이썬 코드로 표현하는 것이 필요함

models.py에 테이블을 정의함

테이블은 다음과 같이 구성됨

  • Publisher - name, street address, city, state/province, country, website
  • Author - name, last name, email address
  • Book - title, publication data, publisher, publication_data
from django.db import models

class Publisher(models.Model):
    name = models.CharField(max_length=30)
    address = models.CharField(max_length=50)
    city = models.CharField(max_length=60)
    state_province = models.CharField(max_length=30)
    country = models.CharField(max_length=50)
    website = models.URLField()

class Author(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=40)
    email = models.EmailField()

class Book(models.Model):
    title = models.CharField(max_length=30)
    authors = models.ManyToManyField(Author)
    # Django 2.0 부터 ForeignKey는 on_delete 속성을 지정해줘야함
    publisher = models.ForeignKey(Publisher,on_delete=models.CASCADE)
    publication_data = models.DateField()

 

models api

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

model 필드 참조

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

 

이 다음은 settings.py INSTALLED_APPS 설정에서 앱을 추가함(만든 앱의 이름이 books이므로 books 추가)

터미널에서 다음 코드를 통해 유효성 검사를 진행

python manage.py check

정상일 경우 'system check is no issues(0 silenced)' 메시지가 출력됨

모델이 유효함을 확인했다면 다음 명령을 통해 장고에게 모델을 변경했다는 것을 알림

python manage.py makemigrations books

마지막으로 다음 명령어를 통해 테이블을 SQLite에 추가함

python manage.py migrate

 

데이터 삽입

모델(테이블)을 생성 후 데이터를 삽입하려면 Django의 고급 파이썬 API를 사용해야함

python manage.py shell

다음을 실행하고 models.py에 정의했던 클래스로 객체를 만들어 값을 전달함

>>> from books.models import Publisher
>>> p1 = Publisher(name='Pupbani',address='277 Ban-Suk',
... city='Dongtan',state_province='Geongi Hwasung',
... country='Korea',website='https://www.pupbai.tistory.com/')

그 후 객체의 save() 메서드를 호출하여 Django가 SQL INSERT 문을 실행하게 함

p1.save()

objects.create() 메서드를 사용해 save() 없이 바로바로 데이터베이스에 저장할 수 있음

>>> from books.models import Publisher
>>> p1 = Publisher.objects.create(name='Pupbani',address='277 Ban-Suk',
... city='Dongtan',state_province='Geongi Hwasung',
... country='Korea',website='https://www.pupbai.tistory.com/')

데이터베이스에 저장된 객체 정보를 가져오려면 objects 특성을 사용함

>>> from books.models import Publisher
>>> publisher_list = Publisher.objects.all()
>>> publisher_list

다음과 같은 코드를 통해 데이터베이스의 모든 Publisher 객체 목록을 가져올 수 있음

 

모델 문자열 표현 추가

all() 메서드를 통해 목록을 출력할 때 객체 구분이 어려워 유용하지 않음

Publisher 클래스에 __str__() 이라는 메서드를 추가하면 이 문제를 해결할 수 있음

예시

def __str__(self):
    return self.name

 

객체 선택

objects.filter(필드=값) 메서드를 통해 원하는 레코드를 검색할 수 있음

filter 메서드의 인수는 여러 개 전달 가능, 2개 이상부터는 SQL AND 절로 변환되어 실행됨

p1 = Publisher.objects.filter(name='Pupbani')
# SELECT * FROM Publisher WHERE name = 'Pupbani';

필드__contains='값' 을 통해 SQL LIKE문을 사용할 수 있음

Publisher.objects.filter(name__contains='Pupbani')
# SELECT * FROM Publisher WHERE name LIKE '%Pupbani%';

Django는 다양한 유형 조회 기능이 존재함

 

Django QuerySet - Filter

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

AND

변수 = 테이블이름.objects.filter(필드1='값1', 필드2='값2')
# 변수 = 테이블이름.objects.filter(필드1='값1' & 필드2='값2')

OR

변수 = 테이블이름.objects.filter(필드1='값1' | 필드2='값2')

 

get() 메서드를 사용해 단일 객체를 가져올 수 있음

객체를 하나도 반환하지 않거여러 개의 객체를 반환하는 쿼리는 예외를 발생

p1 = Publisher.objects.get(name__contains='Pupbani')

 

order_by() 메서드로 정렬 출력을 할 수 있음, 필드의 이름에 '-'를 지정하면 내림차순으로 정렬

Publisher.objects.order_by('name')
Publisher.objects.order_by('-name')

모델 클래스 내부에 class Meta 클래스를 정의하고 ordering = ['필드'] 를 설정하면 order_by()로 명시적 정렬을 하지 않아도 자동으로 객체를 필드로 정렬됨.

class Publisher(models.Model):
    ...
    
    class Meta : 
       ordering = ['name']

 

룩업 체이닝(Chaining lookups)와 출력 결과 조각내기

앞서 나온 필터링과 정렬을 동시에 수행하려면 룩업을 연결하면 됨

Publisher.objects.filter(name__contains='Pupbani').order_by('-name')

실행 코드 뒤에 '[인덱스]' 또는 '[:]' 범위 슬라이싱을 통해 출력 결과 데이터를 추출해서 출력할 수 있음

단! 음수는 사용할 수 없음

Publisher.objects.filter(name__contains='Pupbani').order_by('-name')[0]
Publisher.objects.filter(name__contains='Pupbani').order_by('-name')[0:2]

 

수정과 삭제

update(필드='수정할 값') 메서드를 통해 값을 수정할 수 있음

Publisher.objects.filter(name='Pupbani').update(name='Pupbani1')

반환되는 값은 수정된 레코드 수

 

delete() 메서드를 통해 레코드를 삭제할 수 있음

Publisher.objects.filter(name='Pupbani2').delete()

반환되는 값은 삭제된 개체의 수와 개체의 유형별 삭제 횟수가 있는 사전의 튜플이 반환됨

728x90
반응형

'Back-end & Server > Django' 카테고리의 다른 글

[Django] 폼(Form)  (0) 2023.01.20
[Django] Admin 사이트  (0) 2023.01.16
[Django] 템플릿  (0) 2023.01.01
[Django] 뷰와 URLconfs  (0) 2022.12.28
[Django] Django 시작하기  (0) 2022.12.28