Django - Making queries & query API

Joey Lee·2020년 5월 7일
0

Django

목록 보기
4/23
post-thumbnail

장고 모델에서 모델 클래스를 정의하게 되면, 장고에서는 데이터를 추가/갱신하고 읽어드릴 수 있는 다양한 API들을 자동으로 제공합니다. 이런 기능들은 장고가 ORM 서비스를 제공에 따른 것으로 데이터베이스를 편리하게 핸들링 할 수 있게 도와줍니다.

  • 장고는 디폴트로 모든 모델 클래스에 대해 "objects"라는 Manager (django.db.models.Manager) 객체를 자동으로 추가해서 사용할 수 있음.
  • 이런 기능을 통해 우리는 데이터를 추가/삭제/조회 등을 할 수 있음.
  • 장고 모델 매니저를 사용하기 위해서는 "모델클래스.objects"를 사용함.
  • 객체명이 아니라 클래스명임을 주의 할 것

참고로, 장고에서 데이터를 조회/수정하는 것은 어드민에서도 할 수 있지만, 어드민에서의 사용은 크게 어렵지 않으므로 여기에서는 python manage.py shell에서 진행하는 것을 정리하고자 합니다.

1. Create : 데이터 저장

1) Create objects

# create로 바로 생성하기

Poll.objects.create(question="점심 뭘 먹을까?", pub_date=datetime.now())
# 변수에 객체 담은 후 .save()로 저장

from blog.models import Blog
b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
b.save()

# 객체의 특정 속성 변경해서 저장할 경우,
b.name = 'New name'
b.save()

2) ForeignKey 저장하기

# create로 바로 생성하기
Entry.objects.create(blog_id=1, headline='head')

# 변수에 객체 담은 후 .save()로 저장
from blog.models import Blog, Entry
entry = Entry.objects.get(pk=1)
cheese_blog = Blog.objects.get(name="Cheddar Talk")
entry.blog = cheese_blog
entry.save()

2) ManyToManyField 저장하기

ManyToManyField를 추가할 때는 add 메소드를 활용한다.

from blog.models import Author
joe = Author.objects.create(name="Joe")
entry.authors.add(joe)

2. Retrieving objects

(아래부터는 다른 사례임)

데이터 조회를 위해서는 아래와 같은 메소드를 이용할 수 있습니다.

  • Poll.objects.all() : Poll 클래스의 모든 객체를 리스트로 리턴
  • Poll.obejcts.values() : Poll 클래스 모든 객체의 데이터(딕셔너리 타입)를 리스트에 담아 리턴
  • Poll.objects.filter(question="값") : Poll 클래스의 모든 객체 중 특정 조건이 맞는 객체를 리스트로 리턴 (필터 조건 복수일 수도 있으며, 복수의 객체 리턴 가능함)
  • Poll.objects.get(id=1) : Poll 클래스 중 조건에 맞는 1개의 객체만 리턴함 (인자는 1개여야 함. 객체가 중복으로 리턴되는 것이면 에러 발생)

각각의 코드를 실행했을 때 확인할 수 있는 결과값은 아래와 같습니다.

이 때 주의해야 되는 점은 all(), filter()의 리턴값은 객체가 담긴 리스트이고, get()은 객체라는 것입니다.

따라서 all(), filter()의 리턴값을 변수에 담았다면, 객체의 데이터에 접근하기 위해서는 아래 이미지처럼 a[0].question으로 객체에 먼저 접근한 뒤 해당객체의 프로퍼티를 불러와야 합니다. 반면, get()을 담은 변수는 그 자체가 이미 객체이기에 바로 프로퍼티를 불러와서 사용하면 됩니다.

이 외에 조회시 참고할 만한 메소드들은 아래와 같은 것들이 있습니다.

  • Poll.objects.count() : 데이터(row 수) 수를 리턴
  • Poll.objects.exclude(first_name='Kim') : 특정 조건 제외
  • Poll.objects.order_by('id', -created) : 정렬 순서 id는 오름차순, created는 내림차순
  • Poll.objects.first() : 데이터 중 첫번 째 row 리턴. 반대는 last()
  • 위의 메소드들은 필요에 따라 복수로 사용가능함. 가령, 필터 후 어떤 값 순서로 세워서, 첫 번 째 값만 뽑는다 등

3. Update : 데이터 수정

객체에 담긴 데이터를 수정할 때는 해당 객체를 변수에 담은 후 수정해서 저장하면 됩니다.

4. Detete : 데이터 삭제

해당 row 객체에 접근해서 delete()메소드로 삭제할 수 있습니다. 아래 이미지처럼 바로 삭제할 수도 있고, 변수에 담은 후 삭제할 수도 있습니다.

5. Field lookups

1) 특정필드 값 조건 필터링

Field lookup은 특정한 조건을 충족하는 데이터만을 filter하여 보고 싶을 때 사용한다. filed__lookuptype=value로 하여 사용할 수 있다.

사용할 수 있는 lookuptype으로는 exact, contains, startswith, endswith 등이 있다.

Entry.objects.filter(pub_date__lte='2006-01-01')

# SQL 쿼리문으로는 아래와 같음
SELECT * FROM blog_entry WHERE pub_date <= '2006-01-01';

Entry.objects.get(headline__exact="Cat bites dog")

2) 관계 모델 lookup

참조하고자 하는 object__fieldname로 filtering할 수 있다. 역참조 관계를 참조할 경우에는 모델명의 lowercase를 object명으로 사용하면 된다.

# 정참조 관계인 Blog의 name 기준 필터링 
Entry.objects.filter(blog__name='Beatles Blog')

# 역참조 관계인 Entry의 headline 기준 필터링
Blog.objects.filter(entry__headline__contains='Lennon')

# 여러 개 관계를 뛰어넘어 필터링
Blog.objects.filter(entry__authors__name='Lennon')

3) pk lookup shortcut

편의를 위해, 장고에서는 pk lookup shortcut을 제공한다.
아래 Blog 모델에서 primary key는 id필드이다. 따라서 아래 3가지 쿼리문은 모두 동일한 의미이다.

pk lookup은 맨 아래 예시처럼 조인문에서도 사용할 수 있다.

Blog.objects.get(id__exact=14) # Explicit form
Blog.objects.get(id=14) # __exact is implied
Blog.objects.get(pk=14) # pk implies id__exact

# Get blogs entries with id 1, 4 and 7
>>> Blog.objects.filter(pk__in=[1,4,7])

# Get all blog entries with id > 14
>>> Blog.objects.filter(pk__gt=14)

Entry.objects.filter(blog__id__exact=3) # Explicit form
>>> Entry.objects.filter(blog__id=3)    # __exact is implied
>>> Entry.objects.filter(blog__pk=3)   # __pk implies __id__exact
profile
안녕하세요!

0개의 댓글