터칭 데이터
장고(Django) 쉘에서 데이터 입력하기 본문
쉘에서 데이터 입력하기
지금까지는 어드민 페이지에서 데이터를 입력했었는데요.
이번에는 장고 쉘에서 데이터를 입력해 보겠습니다.
>>> q1 = Question(question_text = "커피 vs 녹차")
>>> q1.question_text
'커피 vs 녹차'
>>> q2 = Question.objects.all()[0]
>>> q2.question_text
'휴가를 어디서 보내고 싶으세요?'
>>> q2 = Question.objects.first()
>>> q2.question_text
'휴가를 어디서 보내고 싶으세요?'
q1 변수에 Question 모델에 "커피 vs 녹차"라는 질문을 새로 만든다고 했습니다.
q1.question_text로 필드명으로 접근해 데이터도 조회가 됩니다.
q2 변수에는 기존에 만들었던 Question의 첫번째 질문을 담습니다.
이제 q1 데이터가 DB 테이블에 잘 저장이 되었을까요?
그렇지 않습니다.
>>> q1.id # 아무 것도 출력되지 않는다.
>>> q2.id
1
q1은 질문을 만들겠다는 과정을 변수에 담은 것 뿐이지 아직은 테이블에 데이터가 입력된 것은 아니기 때문입니다.
그 증거로 q2는 기본키인 id컬럼이 정상적으로 1이라고 출력되지만 q1의 기본키인 id 컬럼은 아무 것도 출력되지 않습니다.
q1.save()를 입력해야 테이블에 정상적으로 데이터가 저장됩니다.
Traceback (most recent call last):
# ~(무수히 많은 에러)~
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<console>", line 1, in <module>
# ~(무수히 많은 에러)~
django.db.utils.IntegrityError: NOT NULL constraint failed: polls_question.pub_date
그런데 쉘에서 세이브를 진행했는데 에러가 뜹니다.
맨 아래를 보면 polls앱의 question 모델의 pub_date 컬럼은 Null 값이 허용되지 않는다는 얘기입니다.
즉, 우리가 q1 변수를 생성할 때 pub_date를 비운 것을 허용하지 않는다는 뜻입니다.
>>> q1.pub_date
>>> q2.pub_date
datetime.datetime(2023, 10, 31, 14, 19, 40, tzinfo=datetime.timezone.utc)
q1.pub_date는 값이 없어 아무 것도 출력되지 않지만
q2.pub_date는 값이 있기 때문에 정상적으로 출력됩니다.
q1 데이터가 정상적으로 입력되도록 q1의 pub_date를 입력해줍시다.
>>> from django.utils import timezone
>>> q1.pub_date = timezone.now()
>>> q1.pub_date
datetime.datetime(2023, 11, 1, 5, 37, 56, 580508, tzinfo=datetime.timezone.utc)
장고의 timezone 라이브러리의 도움을 받아
q1.pub_date에 현재 시간을 넣어줬습니다.
이제는 q1이 테이블에 잘 입력 되었을까요?
>>> q1.save()
>>>
문제 없이 정상적으로 처리 되었습니다.

어드민에서도 잘 입력되어 있습니다.
그런데 매번 pub_date 필드를 timezone 라이브러리의 도움을 받아 손수 입력하는 것은 귀찮을 것 같습니다.
NOT NULL인 pub_date를 우리가 힘쓸 것 없이 자동으로 채워주도록 모델을 고치겠습니다.
polls/models.py 에서
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField(auto_now_add=True) # 처음 question이 만들어 질때 단 한번만 현재 시간 입력
# pub_date = models.DateTimeField(auto_now=True) # question이 업데이트될 때마다 현재 시간 갱신
def __str__(self):
return f'제목: {self.question_text}, 날짜: {self.pub_date}'
DateTimeField에서 auto_now_add를 입력해줍니다.
auto_now와 auto_now_add의 차이는 주석에 적어두었습니다.
지난 시간 모델을 수정하면 장고 쉘을 한번 종료하고 다시 실행시켜줘야 한다고 말씀드렸습니다.
>exit()
...
\mysite>python manage.py shell
>>> from polls.models import *
쉘을 껐다 켜고 models에서 임포트도 마쳤습니다.
>>> from polls.models import *
>>> q3 = Question(question_text = "abc")
>>> q3.save()
>>> q3.pub_date
datetime.datetime(2023, 11, 1, 5, 51, 2, 905096, tzinfo=datetime.timezone.utc)
q3 변수에 pub_date를 담지 않고 "abc"라는 question_text만 담았는데도 불구하고
save()를 진행해도 에러가 나지 않고
q3.pub_date로 시간까지 들어가 있음을 볼 수 있습니다.
기본키&외래키를 준수하며 데이터를 입력하기
우리가 학습에 사용하고 있는 Question 모델과 Choice 모델은 외래키로 관계를 맺고 있는 테이블들입니다.
Choice의 기본키가 외래키 역할로 Question의 기본키를 참조하고 있죠.
이러한 관계를 지키며 데이터를 입력하는 방법은 2가지가 있습니다.
첫번째
.choice_set.create() 메서드 사용후 세이브
>>> q3 = Question(question_text = "abc")
>>> q3.save()
>>> q3.choice_set.all()
<QuerySet []>
>>> q3.choice_set.create(choice_text='a') # 1번
<Choice: a>
>>> q3.choice_set.all()
<QuerySet [<Choice: a>]>
>>> q3.choice_set.create(choice_text='b') # 2번
<Choice: b>
>>> q3.choice_set.all()
<QuerySet [<Choice: a>, <Choice: b>]>
>>> choice_a = q3.choice_set.first()
>>> choice_a.choice_text
'a'
>>> choice_a.votes
0
>>> choice_a.question
<Question: 제목: abc, 날짜: 2023-11-01 05:51:02.905096+00:00>
1번 주석의 코드를 보면 choice_set의 create() 메서드로 Question 테이블에서 questoion_text가 "abc"인 데이터를 참조하는 choice_text가 "a"인 데이터를 만들었습니다. 그 뒤 2번 주석의 코드 역시 choice_text가 "b"이면서 Question 모델에서 question_text가 "abc"인 데이터를 참조하는 Choice 데이터 역시 추가해주었습니다.
두번째
모델 객체()에서 선언 후 세이브
>>> choice_c = Choice(choice_text='c', question=q3)
>>> choice_c.save()
>>> q3.choice_set.all()
<QuerySet [<Choice: a>, <Choice: b>, <Choice: c>]>
Choice 모델의 인자 값에 choice_text와 Question에서 무엇을 참조할지 적어주고 실행하면 데이터가 첫번째 방법과 똑같이 정상 추가됩니다.
'장고 (Django)' 카테고리의 다른 글
장고(Django) 모델 필터링(Model Filtering) (0) | 2023.11.01 |
---|---|
장고(Django) 쉘에서 데이터 수정하고 삭제하기 (0) | 2023.11.01 |
장고(Django) 현재 시간 구하기 (0) | 2023.11.01 |
장고(Django) - 쉘(Shell) & 쉘에서 모델 다루기 (0) | 2023.11.01 |
장고(Django) 어드민으로 모델 등록하기 (0) | 2023.11.01 |