$ django-admin startproject 웹사이트 이름
2의 디렉토리
에는 아래 4가지 파일이 자동으로 생성된다.urls.py
)최상위 URL RESOLUTION은 다음과 같이 작성할 수 있다.
기본으로 제공되는 urls.py
의 내용이 복잡해질 경우, 각각의 app의 디렉토리 밑에 urls.py
를 새로 만들어 주고, 최상위 urls.py
에서 각각에 접근할 수 있도록, urlpatterns 리스트에 추가해 준다.
@ urls.py
from django.contrib import admin # admin 사이트 URL생성용 모듈
from django.urls import include, path # 유저에게 보여줄 사이트 URL생성용 모듈
urlpatterns = [
path('polls/', include('polls.urls')), #include는 다른 urls.py를 참조하러 갈 수 있게 해준다
path('admin/', admin.site.urls),
]
app 디렉토리 하위에 urls.py 를 생성할경우, 다음의 코드를 shell 에서 입력해준다.
( url파일을 복사하여 생성하는 방법이다.)
$ cp <project이름>/urls.py <app이름>/.
각각의 app에 만든 하위 urls.py
는 path에서 VIEW의 정보를 argument 로 받기 때문에, 반드시 views.py
를 import해야한다.
장고에는 많은 framework에 내장된 모듈이 많이 존재한다.
그래서 필요에따라 다양한 요소들을 import해서 사용할 수 있다.
from django.urls import path #path 모듈을 django.urls부터 import
from . import views
urlpatterns = [
path('', views.index, name='index'),
# arg1: 도메인형식
# arg2: render해줄 페이지
# arg3: name (template 작성시 유용하게 쓰임, 필수아님?)
]
$ python manage.py startapp 앱 이름
위의 코드를 실행하면 다음의 파일들이 default로 생성된다.
migrations
디렉토리: hook-up your website (sourcode with database)__init__.py
admin.py
: every website has admin section: Django creates for you by default.apps.py
: settings.py
for appmodels.py
: blueprint of how you are going to store data for the app (where you create Classes).views.py
: python fuction that takes a user's request and give back http responses. (mostly web pages that they requested, such as html)settings.py
):INSTALLED APPS
: settings.py
에 있는 리스트 객체로써, 새로 만든 app은 이곳에 address를 입력하여, 데이터베이스와 싱크할 수 있도록 셋팅해주어야 한다.app이름+Config
으로 만들어 진다.@ settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'polls.apps.PollsConfig',
]
models.py
에 attributes를 추가할 경우에도 migration이 필요하다.)$ python manage.py migrate
# look for INSTALLED_APPS in settings.py and see what tables are needed.
이외 settings.py
에는 다음의 항목들이 존재한다.
BASE_DIR : manage.py
파일이 존재하는 디렉토리
SECRET_KEY : 암호화된 서명을 필요로하는 장고 앱에 사용할 수 있는 키. 임의의 설정 가능.
DEBUG : TEST시 변수들의 다양한 상태 확인 가능, 배포시 FALSE
INSTALLED_APPS : pip설치, 또는 본인이 만든 app을 추가 한다.
MIDDLEWARE_CLASSES : 인증, 보안관련
TEMPLATES : template관련된 설정을 할수 있다. (3세대 부터는 거의 사용X)
DATABASES : 데이터베이스 엔진에 연결 설정 (접속기 역할)
static_url : 정적페이지를 만들 때 사용한다 (css,images,etc), 역시 3세대 부터는 거의 쓰이지 않는다.
models.py
) :models.py
는 이와 관련된 파일이다. 데이터를 서버에 저장하기 위해서는 데이터베이스가 필요하다. 장고는 장고는 ORM을 제공하는데, 이것을 통하여 models.py
를 통해 쉽게 DB를 관리할 수 있다.ORM(Object Relational Mapping), 객체-관계 매핑
객체와 관계형 데이터베이스의 데이터를 자동으로 mapping(연결)해주는 것을 말한다. 객체 지향 프로그래밍은 클래스를 사용하고, 관계형 데이터베이스는 테이블을 사용한다.
객체 모델과 관계형 모델 간에 불일치가 존재한다.ORM을 통해 객체 간의 관계를 바탕으로 SQL을 자동으로 생성하여 불일치를 해결한다.
DB data <—mapping—> Object field 객체를 통해 간접적으로 데이터베이스 데이터를 다룬다.
A model is the single, definitive source of truth about your data.
Django follows the DRY Principle. The goal is to define your data model in one place and automatically derive things from it.Don’t repeat yourself (DRY)
Every distinct concept and/or piece of data should live in one, and only one, place. Redundancy is bad. Normalization is good.
models
를 import해야, 연결이 된다.def __str__(self)
: 해당 객체의 문자열 represntation. 대화식 프롬프트에서 편하게 보려는 이유 말고도, Django 가 자동으로 생성하는 관리 사이트 에서도 객체의 표현이 사용되기 때문에 설정해준다.models.py
의 내용을 변경할 경우, 확인하려면 shell을 재시작해야한다.@ models.py
from django.db import models # ORM이 가능하도록 장고에서 models를 import
class Question(models.Model): # models의 내장함수인 Model을 parameter로 받음.
question_text = models.CharField(max_length=200) #max_length는 CharField의 필수 입력값
pub_date = models.DateTimeField('date published') #argument는 참고하기 위해 human friendly한 문자열로 pub_date의 역할을 설명. argument가 비어도 상관없다.
def __str__(self):
return self.question_text #위에서 정의된 question_text 변수를 문자열로 retrun
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE) #ForeignKey(id#)를 사용하여, Question 과 Choice 클래스를 연결시킨다. #on_delete:models.CASCADE: Question을 지우면 Choice도 같이 지워진다
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
makemigrations
& migration
models.py
를 수정했으므로, 이를 데이터베이스에 반영하기 위하여 migration 작업이 필요하다.settings.py
에서 INSTALLED_APPS
에 app의 address를 먼저 세팅한다. (2번스텝참조)makemigrations
: 모델의 수정내용을 점검하여, DB의 structure를 바꾸어 준다. 이 단계에서는 migrate이 가능한지를 점검해준다. (실제 migration이 일어나지는 않음)migrate
: 실제로 업데이트를 데이터베이스에 반영한다.migrations
디렉토리의 initial.py
에서 수동으로 변경도 가능하다.$ python manage.py makemigrations 앱이름 #make change files
$ python manage.py migrate #actually runs it
admin.py
)$ python manage.py createsuperuser
@admin.py
from .models import 앱이름
admin.site.register(앱이름)
views.py
):views.py
는 데이터를 MODEL에서 가져와 가공하여, 웹페이지 결과를 만들도록 컨트롤 하는 역할을 한다.views.py
안에 있는 하나의 함수(또는 클래스)가 하나의 VIEW를 정의한다from django.http import HttpResponse
def detail(request, question_id):
return HttpResponse("You're looking at question %s." % question_id)
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from .models import Choice, Question
# ...
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
# Redisplay the question voting form.
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "You didn't select a choice.",
})
else:
selected_choice.votes += 1
selected_choice.save()
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
# reverse: VIEW의 함수로부터 역으로 URL을 계산하므로, URL이 바꼈을 때, 변경이 누락되는 일이 없다. (하드코드가 아니기 때문에)
# reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)
from django.http import Http404
from django.shortcuts import render
from .models import Question
# ...
def detail(request, question_id):
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404("Question does not exist")
return render(request, 'polls/detail.html', {'question': question})
@ views.py
# Request/Response 처리를 위해 필요한 모듈들을 import
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views import generic
# MODEL의 클래스들을 import (중요!!)
from .models import Choice, Question
class IndexView(generic.ListView):
template_name = 'polls/index.html' #템플렛의 정의
context_object_name = 'latest_question_list'
def get_queryset(self):
"""Return the last five published questions."""
return Question.objects.order_by('-pub_date')[:5]
class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html'
class ResultsView(generic.DetailView):
model = Question
template_name = 'polls/results.html'
app/urls.py
의 urlpatterns
리스트에 입력된 각각의 패턴을 참조하여 이루어진다.@ app/urls.py
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
# ex: /polls/
path('', views.IndexView.as_view(), name='index'),
# ex: /polls/5/
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
# ex: /polls/5/results/
path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
# ex: /polls/5/vote/
path('<int:question_id>/vote/', views.vote, name='vote'),
]
@ views.py
from django.template import loader #loader를 import
from .models import Choice, Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
#loader가 제공하는 get_template 메소드를 사용하여 template과 연결
template = loader.get_template('polls/index.html')
context = {'latest_question_list': latest_question_list}
#HttpResponse를 return
return HttpResponse(template.render(context, request))
render()
render(request, template_name, context=None, content_type=None, status=None, using=None)
@views.py
from django.shortcuts import get_object_or_404, render #import render
...
from .models import Choice, Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
context = {'latest_question_list': latest_question_list}
return render(request, 'polls/index.html', context)
setting.py
에서 TEMPLATE list에서 초기 상태를 확인 할 수 있다. {% put your code here %}
if you want to end {% endfor %}
{{ put variables here }}
@ #index.html
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
admin.py
and import the new class (if you want to manage it in admin)manage.py
$ python manage.py shell
from 앱이름.models import 클래스1, 클래스2
new_object = Class1()
new_object.attribute1 = ..
new_object.attribute2 = ..
클래스1객체.클래스2_set.all()
클래스2 must be lowercase클래스1객체.클래스2_set.create(attribute = "")
question1.choice_set.all()
>>> <QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Wecode>]>
# automatically saves to DB without using .save()
question1.choice_set.create(choice_text="coding")
잘보고가요~