[TIL] # 26 Django CRUD (1)
지난번에 공부했던 Create에 이어서
Read 보고 가겠습니다
오늘 공부해볼 데이터의 users에 대한 정보구요
READ
get()
User.objects.get(id = 1) User.objects.get(id = 1).email User.objects.get(id = 1).password
하나의 객체를 반환해주는 메서드 입니다
get을 사용하는 경우는 회원의 email을 가지고 온다거나, 아이디를 가지고 오는 등 ...
유니크한 값을 가지고 올때 사용 합니다
하나의 객체를 가지고 오기 때문에 내가 필요한 정보를 .(dot) 을 이용해서
바로 가지고 오면 됩니다
반환하는 개체가 많을 경우
User.objects.get(id__gte = 1)
MultipleObjectsReturned
장고에서 바로 에러를 띄웁니다 😖
filter()
user1 = User.objects.filter(id = 1) user1[0].email user1[0].password
앞에서 봤던 get과는 무언가를 가지고 온다는 비슷한 점이 있는데
다른 점이 있다면, filter의 경우는 쿼리셋을 반환합니다
이 쿼리셋의 경우는 파이썬의 리스트와 비슷하게 작동하기 때문에
리스트를 사용하는 것처럼 사용하면 됩니다
filter 와 list의 차이
list처럼 사용가능 하다는게 list에서 처럼 append가 되고, pop이 되는 등
list의 메서드를 사용가능 하다는게 아닌 순서를 가지고 오는데 있어 비슷하다는 것입니다
위에는 쿼리셋의 메서드, 아래는 list의 메서드
쿼리셋의 경우는 음수 사용이 안됩니다
여러개의 쿼리셋
jungs = User.objects.filter(email__startswith = "jung") google_users = User.objects.filter(email__endswith = "jung")
쿼리셋을 이용해서 정보를 가지고 올 경우
for 문을 이용해서 가지고 올 수 있습니다
exclude()
제외한 나머지를 쿼리셋으로 가지고 옵니다
filter와 같이 쓰는 경우
users = User.objects.filter(email__endswith = "gmail.com").exclude(id =2)
이런식으로 같이 사용하여 google사용자 이지만, id = 2인 유저를 제외한
나머지를 가지고 옵니다
exists()
존재하는지 확인 하는 메서드로
True, False로 반환 합니다
get_or_create()
가지고 오는데, 만약 존재하지 않으면 만들어서 가지고 옵니다
만약 존재하면 False, 존재하지 않으면 True값을 가지고 옵니다
get_or_create의 경우 튜플로 반환 됩니다
count()
해당 테이블에 존재하는, 혹은 filter를 사용해서 가지고 온 쿼리셋의
숫자를 반환 합니다
int 으로 반환 됩니다
first()
가장 첫번째 객체를 반환합니다
last()
가장 마지막 객체를 반환합니다
aggregate()
dictionary 형태로 반환합니다
num_email이 키값, "email"을 가지고 있는 모든 유저의 수가 value 값으로 들어갑니다
어디에 사용할까?
aggregate의 경우는 집계함수를 이용하여 집계되어 나온 값의 수를 구할때 사용합니다
https://docs.djangoproject.com/en/3.1/topics/db/aggregation/
예제가 좋지 않은데 만약 책의 column중 총 페이지의 수가 있다고 치면
책의 총 페이지 갯수 혹은 Avg를 사용하여 모든 책에 대한 페이지의 평균값,
혹은 filter를 이용하여 가지고온 책들의 평균값 등... 을 구할때 사용합니다
values(), values_list()
values의 경우는 dictionary를 포함하는 쿼리셋으로 반환
values_list의 경우는 튜플의 형태로 반환
각각의 column이 key, data가 value값으로 딕셔너리 형태를 이루고 있습니다
select_related
ForeignKey를 사용하는 경우에 사용합니다
# get을 이용해서 가지고 올경우 post1 = Post.object.get(id = 1) # Hit post1.user # Hit post1.user.email # Hit # select_related를 이용해서 가지고 올경우 post2 = Post.objects.select_related('user').get(id = 1) # Hit post2.user post2.user.email
# get을 이용한 쿼리문 print(Post.objects.filter(id = 1).query) >>> SELECT `posts`.`id`, `posts`.`content`, `posts`.`user_id`, `posts`.`created`, `posts`.`updated` FROM `posts` WHERE `posts`.`id` = 1 print(Post.objects.select_related('user').filter(id = 1).query) # select_related를 이용한 쿼리문 >> SELECT `posts`.`id`, `posts`.`content`, `posts`.`user_id`, `posts`.`created`, `posts`.`updated`, `users`.`id`, `users`.`email`, `users`.`password` FROM `posts` INNER JOIN `users` ON (`posts`.`user_id` = `users`.`id`) WHERE `posts`.`id` = 1
ForeignKey로 참조를 하고 있는 상황일때,
get의 경우는 데이터가 필요할 때마다, DB를 Hit해서 데이터를 가지고 옵니다
총 3번의 데이터베이스 Hit이 발생했고
select_related의 경우는 이미 가지고 온 상태이기 때문에
1번의 Hit으로 데이터를 가지고 옵니다
여기서 DB를 Hit하면서 발생하는 시간, 메모리의 손실을 절약 할 수 있습니다
select를 사용해서 가지고 올때, select_related
둘 사이의 순서는 중요하지 않습니다
아아... 머리 다빠진다
Author And Source
이 문제에 관하여([TIL] # 26 Django CRUD (1)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@ddalkigum/TIL-25-1-Django-CRUD-1저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)