본 내용은 https://docs.djangoproject.com/ 의 튜토리얼을 바탕으로 작성되었습니다.
cd /Users / jake_hong/ Djnago_test # 프로젝트를 만들 디렉토리로 이동
$ django-admin startproject mysite1 #mysite1 디렉토리 생성
생성한 mysite1의 디렉토리 내부는 다음과 같다.
outer mysite/ root directory : a container for your project.장고에서 특별히 중요한 부분은 아니며 이름을 언제든 바꿀 수 있다.
manage.py: Django project와 다양한 방법으로 상호작용하는 command-line utility.
mysite1/ : 실제 작동하는 Python package들이 있다.
mysite1/init.py: 해당 디렉토리를 Python package 로 생각하라고 Python에게 알려주는 빈 파일.
mysite1/settings.py: 해당 Django project의 환경을 설정하는 장소.
mysite1/urls.py: Django project의 URL 선언;Django로 선언된 site의 목차.
mysite1/asgi.py: project를 지원하기 위한 ASGI 호환 웹 서버의 시작점.
mysite1/wsgi.py: project를 지원하기 위한 WSGI 호환 웹 서버의 시작점.
cd mysite1 # mysite1 디렉토리
python manage.py runserver # ./manage.py runserver도 됨
아래와 같은 command line이 나온다.
Watching for file changes with StatReloader
Performing system checks...System check identified no issues (0 silenced).
You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
August 27, 2020 - 03:04:23
Django version 3.1, using settings 'mysite1.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
http://127.0.0.1:8000/ 웹 브라우저에 접속 후 “Congratulations!” page가 나오면 서버 작동 확인 완료!
Projects 와 apps 의 차이점은 ?
Projects는 apps와 설정의 집합체
apps는 블로그, 작은 앱과 같은 웹 시스템 , wec projects 안에 있는 요소들
$ python manage.py startapp polls
뷰(view)란?
Django는 웹 요청에 있는 URL을 분석하고 그 결과로 해당 URL에 매핑된 뷰를 호출한다.
뷰의 역할
1. 웹 요청을 받아 데이터베이스 접속 등 애플리케이션의 로직에 맞는 처리를 해줌.
2. 데이터를 HTML로 변환하여 템플릿 처리를 한 후 웹 클라이언트에게 반환해준다.
첫 뷰 만들기
polls/views.pyfrom django.http import HttpResponse def index(request): return HttpResponse("Hello, world. You're at the polls index.")
위에서 말했듯이 뷰를 호출하기 위해서는 URL에 매핑(연결)이 되야 한다.
이를 위해 URLconf가 필요하다.
polls 디렉토리에 URLconf를 만드려면 urls.py에 다음 코드를 넣어준다.(vim urls.py)
URL 연결하기1
polls/urls.pyfrom django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), ]
해당 urls 모듈은 polls의 개인 모듈이며, 최상위 디렉토리(프로젝트)인 mysite1/urls.py에 polls.urls.py 를 연결 해주어야 한다.
아래와 같이 코드를 넣어준다.
URL연결하기2
from django.contrib import admin from django.urls import include, path urlpatterns = [ path('polls/', include('polls.urls')), path('admin/', admin.site.urls), ]
mysite1/urls.py에 polls.urls.py 를 include() 함으로서 polls.urls에 index 뷰가 URLconf에 연결된다.
#/mysite1 경로에서 $ python manage.py runserver # 서버가 구동됨.
웹 브라우저에서 http://localhost:8000/polls/ 확인하면 “Hello, world. You’re at the polls index.”라는 index 뷰에서정의한 텍스트를 볼 수 있다.
추가 공부필요
include()란?
path()란?
path() route
path() view
path() kwargs
path() name
mysite/settings.py 를 연다. 기본적인 Python 모듈로 다양한 Django 세팅을 보여준다. 기본적으로 Django는 SQLite로 세팅이 되어있다. 변경하여 사용하고 싶으면 아래 내용을 참조하여 세팅을 변경하면 된다.
ENGINE – Either 'django.db.backends.sqlite3', 'django.db.backends.postgresql', 'django.db.backends.mysql', or 'django.db.backends.oracle'. Other backends are also available.
NAME – The name of your database. If you’re using SQLite, the database will be a file on your computer; in that case, NAME should be the full absolute path, including filename, of that file. The default value, BASE_DIR / 'db.sqlite3', will store the file in your project directory.
INSTALLED_APPS파일 상단의 설정에는 Django 애플리케이션이 있다.
앱은 여러 프로젝트에서 사용할 수 있으며 다른 프로젝트에서 사용할 수 있도록 패키지화하고 배포 할 수 있다.
기본적 INSTALLED_APPS은 다음과 같다.
위 앱들은 편의를 위해 기본적으로 포함된다.
이러한 애플리케이션 중 일부는 적어도 하나의 데이터베이스 테이블을 사용하므로 사용하기 전에 데이터베이스에 테이블을 만들어야한다.
이를 위해 다음 command를 실행한다.
$ python manage.py migrate
위의 사진처럼 화면이 나오면 데이터베이스가 생성된다.
migrate : /mysite1/settings.py 파일에 있는 INSTALLED_APPS를 보고 필요한 데이터베이스를 만들거나 수정사항을 저장한다. migrate 커맨드를 수행하면 필요한 데이터베이스의 기본 틀이 만들어진다.
-모델 코드 작성
polls/models.py
import datetime from django.db import models from django.utils import timezone class Question(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') def __str__(self): return self.question_text def was_published_recently(self): return self.pub_date >= timezone.now() - datetime.timedelta(days=1) class Choice(models.Model): question = models.ForeignKey(Question, on_delete=models.CASCADE) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0) def __str__(self): return self.choice_text
모델의 코드는 장고에게 많은 정보를 주어준다.
이전에 프로젝트에 polls app이 설치 되어있음을 알려야 한다.
mysite1/settings.py
INSTALLED_APPS = [
'polls.apps.PollsConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
이제 Django는 polls apps 를 을 포함하는 것을 알게 된다.
Model을 활성화하기 전에 makemigrations 명령어로
Django에게 알려준다.
$ python manage.py makemigrations polls
이후 migrate 명령어로 데이터베이스 모델과 관련된 테이블을 생성한다.
$ python manage.py migrate

migration을 자동으로 실행하고 데이터베이스 스키마를 자동으로 관리하라는 명령이 migrate라면, migration 이름을 가져와 SQL을 반환하는 명령은 sqlmigrate이다.
$ python manage.py sqlmigrate polls 0001
Python 대화형 shell에서 Django가 제공하는 무료 API 사용하기.
shell에서 API 탐색하기 (https://docs.djangoproject.com/en/3.1/intro/tutorial02/:튜토리얼 내용)
>> from polls.models import Choice, Question #Make sure our __str__() addition worked. >> Question.objects.all() <QuerySet [<Question: What's up?>]> #Django provides a rich database lookup API that's entirely driven by #keyword arguments. >> Question.objects.filter(id=1) <QuerySet [<Question: What's up?>]> >> Question.objects.filter(question_text__startswith='What') <QuerySet [<Question: What's up?>]> #Get the question that was published this year. >> from django.utils import timezone >> current_year = timezone.now().year >> Question.objects.get(pub_date__year=current_year) <Question: What's up?> #Request an ID that doesn't exist, this will raise an exception. >> Question.objects.get(id=2) Traceback (most recent call last): ... DoesNotExist: Question matching query does not exist. #Lookup by a primary key is the most common case, so Django provides a #shortcut for primary-key exact lookups. #The following is identical to Question.objects.get(id=1). >> Question.objects.get(pk=1) <Question: What's up?> #Make sure our custom method worked. >> q = Question.objects.get(pk=1) >> q.was_published_recently() True #Give the Question a couple of Choices. The create call constructs a new #Choice object, does the INSERT statement, adds the choice to the set #of available choices and returns the new Choice object. Django creates #a set to hold the "other side" of a ForeignKey relation #(e.g. a question's choice) which can be accessed via the API. >> q = Question.objects.get(pk=1) #Display any choices from the related object set -- none so far. >> q.choice_set.all() <QuerySet []> #Create three choices. >> q.choice_set.create(choice_text='Not much', votes=0) <Choice: Not much> >> q.choice_set.create(choice_text='The sky', votes=0) <Choice: The sky> >> c = q.choice_set.create(choice_text='Just hacking again', votes=0) #Choice objects have API access to their related Question objects. >> c.question <Question: What's up?> #And vice versa: Question objects get access to Choice objects. >> q.choice_set.all() <QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]> >> q.choice_set.count() 3 #The API automatically follows relationships as far as you need. #Use double underscores to separate relationships. #This works as many levels deep as you want; there's no limit. #Find all Choices for any question whose pub_date is in this year #(reusing the 'current_year' variable we created above). >> Choice.objects.filter(question__pub_date__year=current_year) <QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]> #Let's delete one of the choices. Use delete() for that. >> c = q.choice_set.filter(choice_text__startswith='Just hacking') >> c.delete() (1, {'polls.Choice': 1})