❓Django method 집중 탐구

yeeun lee·2020년 4월 7일
1

Django

목록 보기
3/8

project, app을 만들다보니 이제 models.py와 urls.py의 기능은 대충 알 것 같다. 그런데 로직을 짜는 views.py를 다루는 것이 너무 어렵다 🤪

앞으로 계속 class-based view를 만들거라 객체objects에 대해서 잘 아는 것이 중요하다. 그런데 객체가 가지고 있는 value를 반환할 때 어떤 method를 써야 결과값을 반환할 수 있는지 헷갈린다 ❗️❗️❗️

그래서 python shell에서 method에 익숙해지기 위해 연습한 내용을 정리해보려고 한다.

1. Setup

1.1 shell 실행

manage.py가 있는 루트 디렉토리에서 python shell을 실행한다.

python manage.py shell

1.2 import class

models에서 만든 테이블을 shell에서 쓰기 위해 가져온다.

from user.models import User 
# user appdml models 파일에서 User class를 가져와주세요.

2. QuerySet?

쿼리셋은 그냥 django orm이 갖고 있는 데이터 타입 중 하나일 뿐이다. 이름자체가 말하듯 sql 쿼리의 집합, 즉 객체의 집합(A collection of objects)이다.

2.1 feature

is lazy

쿼리셋은 lazy evaluation 전략을 따른다. 번역해서 말이 이상한데, value가 필요할 때까지 표현을 delay한다는 뜻이다. 데이터베이스에 접근해 evaluted하기 전 까지 쿼리셋은 바뀌지 않는다.

QuerySet aren’t fetched from the database until you “ask” for them. When you do, the QuerySet is evaluated by accessing the database.

used by chaining filter

쿼리셋과 상호작용할 때는 주로 필터를 돌릴 때이다. filter로 chaining하기 위해서 대부분의 Queryset은 새로운 Queryset을 반환한다.

2.2 주의 사항

해당 데이터 타입은 django에만 있기 때문에, json 에서 읽을 수 있게 만들어주려면 list로 감싸야 한다. list로 감싸면 쿼리셋이 없어진다. list로 만들고 인덱스 지정 후 dot notation을 써야 value 접근이 가능하다... 후 길어

>>> a = Comment.objects.filter(user='chun')
>>> a
<QuerySet [<Comment: Comment object (2)>, <Comment: Comment object (4)>]>
>>> list(a)
[<Comment: Comment object (2)>, <Comment: Comment object (4)>]

3. method

이제 value를 가져오는 방법에 대해 알아보자. 예시는 user app models.py에서 만든 User class를 기반으로 할 것이다.

shell에서 사용할 때 명령어가 길기 때문에 임의의 변수(a,b,c...)에 할당해서 사용하는 것이 편하다.

3.1 all()

database에서 모든 class 객체를 가지고 있는 쿼리셋을 반환한다. (returns a QuerySet that contains all User objects in the database)

모든 객체를 검색하고 싶다면 해당 method를 사용한다. 객체로 표현되기 때문에 내부에 있는 value를 사용하려면 다음과 같이 dot notation을 사용해야 한다.

a = User.objects.all()
<QuerySet 
	[<User: User object (1)>, 
	 <User: User object (2)>, 
	 <User: User object (3)>]>

a[0].user # output: 'yeni' - 0번째 쿼리셋의 users value를 보여줘
a[0].password # output: 123 

3.2 values()

User.objects.all() 상태에서 쿼리셋 안에 있는 value들을 보여주는 상태다. 리스트 내부가 객체가 아닌 딕셔너리로 구성되어 있기 때문에 위와 다르게 value를 가져올 때 sqaure bracket을 사용한다.

b = User.objects.values()
<QuerySet 
	[{'id': 1, 'user': 'yeni', 'password': '123'}, 
 	 {'id': 2, 'user': 'chun', 'password': '1234'}, 
 	 {'id': 3, 'user': 'marble', 'password': '00'}]>
    
b[0]['user'] # output: 'yeni' 
b[0]['password'] # output : 123 

method를 사용했던 상황
내가 여태까지 post로 받은 데이터를 한꺼번에 보고 싶을 때 사용했다. 아래 user는 Queryset 안에 있기 때문에, list로 감싸면 Queryset 형태에서 list 형태로 변한다.

class UserView(View):
	user = User.objects.values()
    	return JsonResponse({'user_info':list(user)}, status=200)

3.3 filter()

filter는 항상 쿼리셋을 반환하고, 반환되는 객체는 리스트 안에 담겨있다.

c = User.objects.filter(user='yeni')
<QuerySet [<User: User object (1)>]>

c[0].user # output: 'yeni'
c[0].password # output: 123 

method를 사용했던 상황
return값을 보기 보다는 쿼리셋의 객체가 특정 값을 갖고 있는지 확인할 때 사용했다.

class signupView(View):
	data = json.loads(request.body)
    login_id = data.get('user_id', None) 
    login_password = data.get('password', None)
    
    if User.objects.filter(user_id=login_id):
    	return JsonResponse({'message': 'DUPLICATE_USER'}, status=401)

filter(key=value).exists()

Boolean return 값을 갖는 method. 객체가 value를 가지고 있으면 True, 아니면 False를 return한다. if문에서 expression이 True일 경우 실행되는 상황에서 쓰일 수 있다.

a = User.objects.filter(user_id='yeni').exists()
a  # True

3.4 get()

딕셔너리 값을 가져오는 방법 중 하나인데, 1개의 값만 가져온다. filter와 동일하지만 하나의 결과값만 가져온다고 보면 된다. 유일하게 얘만 쿼리셋이 없다.

파라미터에 들어온 값과 일치하는 객체를 찾아주고, 다른 method와 다르게 리스트 안에 담겨있지 않아 바로 Dot notation으로 사용이 가능하다.

d = User.objects.get(user='yeni')
<User: User object (1)>

d.user # output: 'yeni'
d.password # output: 123 

b = {'user_id': 'chunchun', 'password':12345}
b.get('user_id') # output: 'chunchun'

method를 사용했던 상황
딕셔너리가 특정 값을 갖고 있을 때 저장하는 용도로 사용한다. None은 옵션이지만 코드 가독성을 높이기 위해 사용한다. 값을 갖고 있지 않을 경우 값을 리턴하진 않고, print했을 때 None이 뜬다.

class signupView(View):
	data = json.loads(request.body)
    login_id = data.get('user_id', None) 
    login_password = data.get('password', None)
    
	if User.objects.filter(user_id=login_id):
		return JsonResponse({'message': 'DUPLICATE_USER'}, status=401)

아래 링크를 들어가면 queryset 관련 method를 확인할 수 있다. 우선 이 정도로 정리!

https://docs.djangoproject.com/en/3.0/ref/models/querysets/#queryset-api

profile
이사간 블로그: yenilee.github.io

1개의 댓글

comment-user-thumbnail
2021년 3월 9일

views.py 로직 짜기 너무 어려워요ㅠ 잘 정리해주셔서 힘 얻고 갑니다!!

답글 달기