참고 : Part 1: Requests and responses | Part 2: Models and the admin site | Part 3: Views and templates | Part 4: Forms and generic views | Part 5: Testing | Part 6: Static files | Part 7: Customizing the admin site
$ django-admin startproject mysite
위 명령어를 입력하면 아래와 같이 파일들이 생성됨
mysite/
manage.py (Django 프로젝트와 다양한 방법으로 상호작용 하는 커맨드라인의 유틸리티)
mysite/ (디렉토리 내부에 프로젝트를 위한 실제 Python 패키지들이 저장)
__init__.py (이 디렉토리를 패키지처럼 다루라고 알려주는 용도의 빈 파일)
settings.py (현재 Django 프로젝트의 환경 및 구성을 저장)
urls.py (Django project 의 URL 선언을 저장)
asgi.py (현재 프로젝트를 서비스하기 위한 ASGI 호환 웹 서버의 진입점)
wsgi.py (현재 프로젝트를 서비스하기 위한 WSGI 호환 웹 서버의 진입점)
WSGI는 ASGI이전의 Python의 표준
ASGI는 WSGI의 상위 호환으로 web server와 프레임워크(django), 애플리케이션을 연결 해주는 Python의 표준 API
/manage.py
가 있는 곳에서 아래 명령어를 실행하면 8000번 포트에서 실행됨
python manage.py runserver
다른 포트에서 열고싶다면 맨 끝에 원하는 포트번호를 추가해주면 된다.
+) 대화형으로 실행할 수도 있음
$ python manage.py shell
1. 앱 기본 디렉토리 구조 생성하기
2. `/app/view.py` 에 요청에 대한 응답 구조 작성하기
3. `/app/urls.py` 에서 url에 뷰를 연결하기
4. `/mysite/urls.py` 에 새로 만든 앱의 url을 연결하기
$ python manage.py startapp polls
위 명령어로 polls 라는 디렉토리를 만들면 아래와 같은 구조가 생성됨
polls/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
polls/view.py
내부에 요청에 대한 응답 작성
from django.http import HttpResponse
def index(req):
return HttpResponse("Hello, world. You're at the polls index.")
polls/urls.py
파일을 만들고 urlpatterns
를 작성
from django.urls import path
from.import views
urlpatterns = [
path('', views.index, name='index'),
]
mysite/urls.py
파일 내부 urlpatterns
에 새로 만든 앱의 url을 추가
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]
include: include()
함수는 다른 URLconf들을 참조
Django가 함수 include()를 만나게 되면 URL의 그 시점까지 일치하는 부분을 잘라내고, 남은 문자열 부분을 후속 처리를 위해 include 된 URLconf로 전달
path(route, view, kwargs, name)
route : 연결될 url
view: 연결될 view
kwargs: 임의의 키워드 인수들이 view에 딕셔너리로 전달됨
name: url에 이름을 추가할 수 있고, 템플릿을 포함한 Django 어디에서나 이 이름으로 명확하게 참조 가능
mysite/settings.py
에서 데이터베이스 설정
mysql 사용시 mysqlclient
설치 필요
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'test_db',
'USER': 'root',
'PASSWORD': 'root',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
+) 타임존을 한국 기준으로 설정
When USE_TZ is False, this is the time zone in which Django will store all datetimes.
When USE_TZ is True, this is the default time zone that Django will use to display datetimes in templates and to interpret datetimes entered in forms.
데이터베이스에 저장할때 한국 기준시간으로 저장하려면 USE_TZ는 False 해주어야함
TIME_ZONE = 'Asia/Seoul'
USE_TZ = False
+) 세팅 파일을 보면 INSTALLED_APP이 있는데 다음의 앱들을 포함함
필요 없는 앱들은 지우거나 주석처리 해도 무관함
- django.contrib.admin – 관리용 사이트
- django.contrib.auth – 인증 시스템
- django.contrib.contenttypes – 컨텐츠 타입을 위한 프레임워크
- django.contrib.sessions – 세션 프레임워크
- django.contrib.messages – 메세징 프레임워크
- django.contrib.staticfiles – 정적 파일을 관리하는 프레임워크
이 앱들은 데이터베이스 테이블이 필요하므로 테이블들을 미리 만들어주어야 Django를 실행시켰을때 정상적으로 동작함.
따라서 아래의 명령어를 미리 실행.
$ python manage.py migrate
from django.db import models
import datetime
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 "%s, %s" % (self.question_text, self.pub_date )
# 커스텀 메소드 추가(최근에 수정되었는지 여부 확인)
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 "%s, %s" % (self.choice_text , self.votes)
class Meta:
managed = False
db_table = 'receivers' # 테이블 이름
verbose_name_plural = '받는 분' # 어드민 페이지 네비게이션 바에 나타나는 이름
def __str__(self)
은 str()
실행시 해당 리턴값을 반환함. 따라서 읽기 쉬운 값을 반환할 필요가 있음+) 이미 있는 모델 감지
python manage.py inspectdb
만든 모델을 적용시키면 데이터베이스 스키마와 모델에 접근하기 위한 python 데이터베이스 접근 api 가 생성되는데, 그러기 위해서는 polls 라는 앱이 설치되어있다는것을 mysite/settings.py
파일에서 명시해주어야 함
PollsConfig
클래스는 polls/apps.py
파일 내에 존재. 따라서, 점으로 구분된 경로는 'polls.apps.PollsConfig'
INSTALLED_APPS = [
...
'polls.apps.PollsConfig',
]
$ python manage.py makemigrations polls
결과는 다음과 같음
Migrations for 'polls':
polls\migrations\0001_initial.py
- Create model Question
- Create model Choice
$ python manage.py migrate
+) 다음 명령어를 실행하면 실제로 마이그레이션할때 사용되는 sql문을 볼 수 있음
$ python manage.py sqlmigrate polls 0001
from polls.models import Choice, Question
from django.utils import timezone
q = Question(question_text="What's new?", pub_date=timezone.now())
q.save()
q.question_text = "What's up?"
q.save()
여기까지는 save() 해야 저장됨
여기부터는 save() 안해도 저장됨
# 조회
q.choice_set.all()
# 생성
q.choice_set.create(choice_text='Not much', votes=0)
q.choice_set.create(choice_text='The sky', votes=0)
c = q.choice_set.create(choice_text='Just hacking again', votes=0)
c.delete()
p.delete()
$ python manage.py createsuperuser
Username: admin
Email address: admin@example.com
Password: **********
Password (again): *********
Superuser created successfully.
명령어 입력후 유저네임, 이메일, 비밀번호를 입력하면 생성 후 /admin
으로 접속
polls/admin.py
파일을 변경
from django.contrib import admin
from .models import Question,Choice
admin.site.register(Question)
admin.site.register(Choice)
속성 순서 변경
polls/admin.py
파일을 변경
from django.contrib import admin
from .models import Question,Choice
class QuestionAdmin(admin.ModelAdmin):
fields = ['pub_date', 'question_text']
admin.site.register(Question, QuestionAdmin)
admin.site.register(Choice)
속성 분류
polls/admin.py
파일을 변경
from django.contrib import admin
from .models import Question,Choice
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date']}),
]
admin.site.register(Question, QuestionAdmin)
admin.site.register(Choice)
참조되는 쪽에서 값을 추가하기 (인라인)
from django.contrib import admin
from .models import Question,Choice
# Question에 추가될 Choice 항목 구성
class ChoiceInline(admin.StackedInline):
# 대상모델
model = Choice
#기본으로 생성되는 항목 개수
extra = 0
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {
'fields': ['pub_date'],
'classes': ['collapse'] # 숨기기 옵션 추가
}
),
]
# 인라인으로 Choice 모델 추가
inlines = [ChoiceInline]
admin.site.register(Question, QuestionAdmin)
ChoiceInline
의 부모를 바꿔주면 됨class ChoiceInline(admin.TabularInline):
...
row 형태 변경
class QuestionAdmin(admin.ModelAdmin):
...
list_display = ('question_text', 'pub_date', 'was_published_recently')
머리글을 클릭할 경우 정렬이 지원되나 커스텀 메소드 결과에 따른 정렬은 지원되지 않음
+) 커스텀 메소드 결과로 정렬하고 싶다면 모델에 display() 데코레이터를 이용해야함
# polls/models.py
from django.contrib import admin
class Question(models.Model):
...
@admin.display(
boolean=True,
ordering='pub_date',
description='Published recently?',
)
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date <= now
어드민 파일에 필터도 추가 가능
# polls/admin.py
class QuestionAdmin(admin.ModelAdmin):
...
list_filter = ['pub_date']
# polls/admin.py
class QuestionAdmin(admin.ModelAdmin):
...
search_fields = ['question_text']
★ join으로 인한 속도 저하 문제 해결법
class modelAdmin(admin.ModelAdmin):
list_select_related = ['column_name']
연관해서 가져올 항목을 제한해주면 됨
html 파일을 직접 변경
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
templates/admin
에 django/contrib/admin/templates/admin/base_site.html
파일을 복사
Django 소스파일 위치:
$ python -c "import django; print(django.__path__)"
AdminSite
오브젝트를 이용해 변경
admin.py
from django.contrib import admin
from .models import *
from .resources import *
@admin.action(description='Chage To Draft')
def ChangeToDaft(modeladmin, request, queryset):
queryset.update(status='Draft')
class BrandAdmin(ImportExportMixin, admin.ModelAdmin):
list_display = ('title', 'status')
actions = [ChangeToDaft]
admin.site.register(Article, ArticleAdmin)
Django 프로젝트와 Admin 페이지 초기 세팅방법 배워갑니다. 좋은 글 감사합니다!