Django 넌 또 뭐냐 . . .
Django 파이썬으로 만들어진 무료 오픈소스 web application framework
urlresolver 패턴 목록을 가져와 URL과 맞는지 처음부터 하나씩 대조하여 식별, 일치한다면 view한테 인계
view 수정할 수 있는 권한이 있는지 확인 후 그에 관한 값을 생성
manage.py : 스크립트, 사이트 관리 도와주는 역할
setting.py : 웹사이트 설정이 있는 파일
urls.py : urlresolver가 사용하는 패턴 목록 포함
object 객체 : 객체가 있고 그에 관련된 객체 속성(properties), 행위는 메서드
어플리케이션을 만들기 위해 콘솔창 (djangogirls 디렉토리에서 manage.py) 에서 아래 명령어
구조는 Class를 이용해서 짜야 한다.
.CharField - 글자 수가 제한된 텍스트를 정의할 때 사용합니다. 글 제목같이 짧은 문자열 정보를 저장할 때 사용
.TextField - 글자 수에 제한이 없는 긴 텍스트를 위한 속성
.DateTimeField - 날짜와 시간을 의미
.ForeignKey - 다른 Class에 대한 링크를 의미
Model field reference | Django documentation | Django
Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate
docs.djangoproject.com
필드 타입
모델의 필드에는 다양한 타입들이 있는데, 필드 타입에 대한 자세한 정보는 여기 Django 필드 타입 링크를 참고하면 된다. 모든 필드 타입 클래스들은 추상클래스인 "Field" 클래스의 파생클래스들이다. 아래는 주요 필드 타입에 대한 간단한 요약이다.
Field Type설명
CharField | 제한된 문자열 필드 타입. 최대 길이를 max_length 옵션에 지정해야 한다. 문자열의 특별한 용도에 따라 CharField의 파생클래스로서, 이메일 주소를 체크를 하는 EmailField, IP 주소를 체크를 하는 GenericIPAddressField, 콤마로 정수를 분리한 CommaSeparatedIntegerField, 특정 폴더의 파일 패스를 표현하는 FilePathField, URL을 표현하는 URLField 등이 있다. |
TextField | 대용량 문자열을 갖는 필드 |
IntegerField | 32 비트 정수형 필드. 정수 사이즈에 따라 BigIntegerField, SmallIntegerField 을 사용할 수도 있다. |
BooleanField | true/false 필드. Null 을 허용하기 위해서는 NullBooleanField를 사용한다. |
DateTimeField | 날짜와 시간을 갖는 필드. 날짜만 가질 경우는 DateField, 시간만 가질 경우는 TimeField를 사용한다. |
DecimalField | 소숫점을 갖는 decimal 필드 |
BinaryField | 바이너리 데이타를 저장하는 필드 |
FileField | 파일 업로드 필드 |
ImageField | FileField의 파생클래스로서 이미지 파일인지 체크한다. |
UUIDField | GUID (UUID)를 저장하는 필드 |
위와 같은 필드 타입 클래스 이외에, Django 프레임워크는 테이블 간 혹은 필드 간 관계(Relationship)을 표현하기 위해 ForeignKey, ManyToManyField, OneToOneField 클래스를 또한 제공하고 있다. 특히 ForeignKey는 모델 클래스간 (혹은 Underlying 테이블 간) Many-To-One (혹은 One-To-Many) 관계를 표현하기 위해 흔히 사용된다. 이 부분에 대한 보다 자세한 내용은 이 링크를 참조한다.
필드 옵션
모델의 필드는 필드 타입에 따라 여러 옵션(혹은 Argument)를 가질 수 있다. 예를 들어, CharField는 문자열 최대 길이를 의미하는 max_length 라는 옵션을 갖는다. 필드 옵션은 일반적으로 생성자에서 아규먼트로 지정한다. 다음은 모든 필드 타입에 적용 가능한 옵션들 중 자주 사용되는 몇가지를 요약한 것이다.
필드 옵션설명
null (Field.null) | null=True 이면, Empty 값을 DB에 NULL로 저장한다. DB에서 Null이 허용된다. 예: models.IntegerField(null=True) |
blank (Field.blank) | blank=False 이면, 필드가 Required 필드이다. blank=True 이면, Optional 필드이다. 예: models.DateTimeField(blank=True) |
primary_key (Field.primary_key) | 해당 필드가 Primary Key임을 표시한다. 예: models.CharField(max_length=10, primary_key=True) |
unique (Field.unique) | 해당 필드가 테이블에서 Unique함을 표시한다. 해당 컬럼에 대해 Unique Index를 생성한다. 예: models.IntegerField(unique=True) |
default (Field.default) | 필드의 디폴트값을 지정한다. 예: models.CharField(max_length=2, default="WA") |
db_column (Field.db_column) | 컬럼명은 디폴트로 필드명을 사용하는데, 만약 다르게 쓸 경우 지정한다. |
가상환경 만들고
python3 -m venv "폴더이름"
source "폴더이름/bin/activate"
pip install --upgrade pip
pip3 install Django
django-admin startproject 프로젝트이름"
python3 manage.py startapp "서브젝트이름"
설치 이후 진행 관련 이야기
- project 만들기
- django-admin startproject {project의 이름}
- 서버 실행
- python manage.py runserver
- 앱 만들기
- python manage.py startapp {앱 이름}
- 프로젝트 안의 setting.py에 자식이라고 정의를 내려야 한다 (settings.py 안에 보면 INSTALLED_APPS 라는 리스트가 있을 텐데 그 리스트에 추가를 해줍니다. {app이름}.apps.{app이름(맨 앞이 대문자)}Config'
- html 만들기
- 한 개 일수도 있지만, 여러개의 html 파일이 존재할 수도 있음
- templates라는 디렉토리 만들고 안에 담아야 함
- 동작하는 함수 만들기
- 함수는 myapp 안에 views.py에서 정의, request가 들어왔을 때 home.html 불러주는 함수
- def home(request) : return render(request, 'home.html') → views.py 안에 정의
- url 설계
- 해당 url로 접근 시, views.py에 있는 함수를 실행 시키고, 그 함수가 html 파일을 띄워주는 원리
- urlpatterns = [ path('admin/', admin.site.urls), path(' ', myapp.views.home, name='home'), ]
데이터 관리 모델
from django.db import models class Question(models.Model): subject = models.CharField(max_length=200) # CharField 글자 수 제한 content = models.TextField() # TextField글자수 제한 없는 create_date = models.DateTimeField() # 날짜 및 시간 관련 속성 def __str__(self): return self.subject class Answer(models.Model): # ForeignKey 다른 모델과의 연결, on_delete 연결된 질문이 삭제되면 답변 삭제 question = models.ForeignKey(Question, on_delete=models.CASCADE) content = models.TextField() create_date = models.DateTimeField() |
위에서 만든 모델을 이용하여 테이블을 생성하자. 테이블 생성을 하려면 config/settings.py 파일에서 INSTALLED_APPS 항목에 "사용하는 앱"을 추가 (앱 추가 관련되어서는 위에 설명)
migrate로 테이블 생성
makemigration로 테이블 작업 파일 생성
migrate 실행 (등록된 앱에 있는 모델을 참조 실제 테이블을 생성)
이후 장고 셸 실행으로 모델 사용
python manage.py shell >>> from pybo.models import Question, Answer # 장고 셸에 임포트 >>> from django.utils import timezone >>> q = Question(subject='pybo가 무엇인가요?', content='pybo에 대해서 알고 싶습니다.', create_date=timezone.now()) >>> q.save() >>> q.id 1 >>> q = Question(subject='장고 모델 질문입니다.', content='id는 자동으로 생성되나요?', create_date=timezone.now()) >>> q.save() >>> q.id 2 >>> Question.objects.all() # Question 모델 데이터 조회 <QuerySet [<Question: Question object (1)>, <Question: Question object (2)>]> 위의 결과는 데이터 유형을 출력한 것이므로 사람이 보기 불편하다. 이때 Question 모델에 __str__ 메서드를 추가하면 된다. 파일 이름 : pybo/models.py class Question(models.Model): def __str__(self): return self.subject >>> from pybo.models import Question, Answer >>> Question.objects.all() <QuerySet [<Question: pybo가 무엇인가요?>, <Question: 장고 모델 질문입니다.>]> # 조회 관련 >>> Question.objects.filter(id=1) # 모델 데이터 조회 <QuerySet [<Question: pybo가 무엇인가요?>]> >>> Question.objects.get(id=1) # 모델 데이터 하나만 조회 <Question: pybo가 무엇인가요?> >>> Question.objects.filter(subject__contains='장고') <QuerySet [<Question: 장고 모델 질문입니다.>]> # 데이터 수정 >>> q = Question.objects.get(id=2) >>> q <Question: 장고 모델 질문입니다.> >>> q.subject = 'Django Model Question' >>> q.save() # 데이터 삭제 >>> q = Question.objects.get(id=1) >>> q.delete() # 데이터 연결 >>> q = Question.objects.get(id=2) >>> q <Question: Django Model Question> >>> from django.utils import timezone >>> a = Answer(question=q, content='네 자동으로 생성됩니다.', create_date=timezone.now()) >>> a.save() >>> a = Answer.objects.get(id=1) >>> a <Answer: Answer object (1)> >>> a.question <Question: Django Model Question> >>> q.answer_set.all() <QuerySet [<Answer: Answer object (1)>]> |
템플릿 태그의 3가지 유형 : 분기, 반복, 객체 출력
분기 템플릿 태그 | 반복 템플릿 태그 | 객체 출력 태그 |
{% if 조건문1 %} <p>조건문1에 해당되는 경우</p> {% elif 조건문2 %} <p>조건문2에 해당되는 경우</p> {% else %} <p>조건문1, 2에 모두 해당되지 않는 경우</p> {% endif %} |
{% for item in list %} <p>순서: {{ forloop.counter }} </p> <p>{{ item }}</p> {% endfor %} |
{{ question }} {{ question.id }} {{ question.subject }} |
템플릿 태그
{% if question_list %} | : question_list가 있다면 |
{% for question in question_list %} | : question_list를 반복하며 순차적으로 question에 대입 |
{{ question.id }} | : for 문에 의해 대입된 question 객체의 id 출력 |
{{ question.subject }} | : for 문에 의해 대입된 question 객체의 subject 출력 |
forloop 객체 속성
forloop.counter | : for 문의 순서로 1부터 표시 |
forloop.counter0 | : for 문의 순서로 0부터 표시 |
forloop.first | : for 문의 첫 번째 순서인 경우 True |
forloop.last | : for 문의 마지막 순서인 경우 True |
템플릿 | Django 문서 | Django
Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate
docs.djangoproject.com
하드 코딩 URL 을 방지 하기 위한 발버둥
<li><a href="/pybo/{{ question.id }}/">{{ question.subject }}</a></li> |
urls.py 수정하여 URL 별칭으로 적용 path('<int:question_id>/', views.detail, name='detail'), *.html 템플릿에서 URL 별칭 사용 <li><a href="{% url 'detail' question.id %}">{{ question.subject }}</a></li> |
urls.py 네임스페이스 추가 app_name = 'pybo' *.html 템플릿 수정 <li><a href="{% url 'pybo:detail' question.id %}">{{ question.subject }}</a></li> |
URL 별칭의 사용 : redirect
redirect('pybo:detail', question_id=question.id)
여기부터 다시 시작