Django Urls, Views, Models

Gom La·2023년 4월 3일
0

장고와 친해지기

목록 보기
6/17
post-thumbnail

🔖 Django 동작 흐름

Django를 이용하여 웹 프로젝트를 만들기 위해선 Django가 동작하는 흐름을 먼저 파악해야한다.

전체적인 흐름을 파악하기도 전에 코드 작성에 들어가, 지금 내가 작성하는 코드가 어떤 파트에서 어떤 역할을 하는지 모르는 것은 의미없는 타이핑이나 마찬가지이다.

물론 따라하며 코드를 작성하면 완성된 무언가는 만들 수 있겠지만, 나만의 프로젝트나 다음에 동일한 코드가 추가되어야 할때 기억이 나지 않을 뿐더러 또 이전에 따라 작성한 코드를 반복해서 봐야하기 때문이다.

Django를 이용한 프로그래밍을 시작하기 전에 전체적인 동작 흐름을 파악해보자.

  1. Client : 웹 브라우저에서 웹 서버(Web Server) 에 필요한 요청을 하고 그에 맞는 응답을 받는 사용자를 클라이언트 라고 한다.
  2. Web Server : 개발시에는 Django에 내장된 웹 서버(Web Server) 를 이용하며 배포하고 운영하는 프로젝트는 Nginx / Apache 를 이용한다.
  3. WSGI : Web Server와 Django Framework를 연결 하기 위해 사용한다.
  4. Request : 사용자의 요청 이 전달된다.
  5. URL Resolution : urls.py 파일 에서 요청한 주소를 잘게 나눠준다.(== Parsing)
  6. View : 잘게 나누어진 주소는 역할에 맞게 view로 이동, Web application에 각각 맞는 작업을 하기위한 작성한 코드가 있다. 요청받은 데이터를 저장하거나, DATABASE 에서 꺼내오거나 등 역할에 맞는 기능을 개발
  7. Template : 디자인 을 담당한다.
  8. Response : 요청에 대한 응답 을 한다.

🔖 URLs 라우팅

위의 구조에 따르면 URL Resolution 순서에 urls.py파일에서 요청한 주소를 잘게 나눠주는 역할을 하고 있다.

간단하게 얘기하면 urls.py에서 요청한 주소와 주소에 맞는 view(기능)을 맵핑 또는 라우팅 하는 역할을 하고 있다.

➤ 라우팅 코드

📌 shortener/urls.py

from django.urls import path

from shortener.views import index_view, redirect_view

urlpatterns = [
    path('', index_view, name='index'),
    path('redirect/', redirect_view)
]

위와 같이 urlpatterns 리스트안에 path()로 경로를 지정하는데, path()의 인수로 요청 주소, 요청한 주소에 라우팅되는 함수, 명칭을 전달해 주면 된다.

➤ urls.py 분리

단 위의 라우팅 이전에 App별로 url을 분리하기 위해 사전작업을 진행하였다.

이 작업을 하는 이유는 App 별로 요청 주소를 관리하기 위해서이다.

하나의 프로젝트에 여러가지 App이 존재하는데 이 모든 App의 url요청을 하나의 urls.py에서 관리하기에는 코드도 정신없고 유지보수하기도 어렵기 때문이다.

📌 config/urls.py

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path("admin/", admin.site.urls),
    path("shortener/", include('shortener.urls'))
]

shortener/로 전위 주소를 명명한 후 include() 함수로 shortener.urls로 이동하게 설정하였다.

위와 같이 경로를 지정하면 shortener에 해당하는 url주소는 다음과 같이 첫 주소에 shortener를 붙여서 주소를 호출하게 된다.

127.0.0.1:8000/shortener

🔖 Views 작성

urls.py 에서 요청 주소에 대한 라우팅을 진행하였다.

라우팅을 진행할 때 path()에 인자로 요청주소요청주소에 라우팅 되는 함수를 보내주는데 이 함수가 view에서 작성된 함수로 이동한다.

📌 shortener/urls.py

path('', index_view, name='index'),

urls.py에서 작성된 ''값의 주소요청을 먼저 살펴보면 요청한 주소가 ''값 이지만 url을 분리시키기 위해 'shortener'를 추가 했기 때문에 사실상 요청 주소는 '/shortener/'가 된다.

요청 주소에 매칭되어 있는 함수는 index_view 이기 때문에 views.py에있는 저 함수 내에 주소에 해당하는 기능을 작성하면 된다.

📌 shortener/views.py

def index_view(request):
	# 진입 확인 print()
    print("진입 index_view")
    
	# ORM을 이용한 사용자 계정 조회
	Users.objects.filter(username='admin').first()
    email = user.email if user else "Anonymous User!"
    
    print(email)
    
    # render()를 이용한 template이동 및 context전달
    return render(request, "index.html", {"welcome_msg" : f"Hello {email}!", "hello" : "World"})
  1. index_view로 함수 작성 - 매개변수는 request 를 꼭 받아야 한다.
    • view로 들어올때 여러가지 middleware를 거치는데 이 middleware에서 request를 전달해주기 때문이다.
  2. 진입확인을 위한 print()작성
  3. ORM을 이용한 사용자 계정 조회
    python3 manage.py createsuperuser
    • 생성된 사용자 계정이 존재하지 않은 경우에 생성해 주자.
    • 사전에 확장시켜 생성한 Users모델, 즉 Users 테이블에 저장되어 있는 데이터를 ORM을 통해 조회
    • [모델명].objects 를 통해 모델 객체 불러오기
    • [모델명].objects.filter([필드]='[조건]').last()를 통해 테이블에 있는 데이터를 조회하여 객체로 변환
    • 객체로 변환된 값을 user에 할당
  4. 사용자 계정의 이메일 정보 조회
    • user 모델에 email필드가 존재하기 때문에 할당된 변수 객체, user.email을 선언하면 [필드]='[조건]'으로 불러온 사용자에 대한 이메일 정보를 조회 할 수 있다.
  5. render()를 통해 요청정보, 이동할 template, 전달할 context를 인자로 전달하면 이동할 template에 전달할 context와 요청정보를 가지고 화면이동이 가능하다.
    • 여기서 '전달할 context'는 딕셔너리 형태로 전달해야한다.
    • 본인은 'welcome_msg'키값에 f'Hello {email}!'값을, 'hello'키값에 'World'를 전달하려고 한다.

🔖 Templates 렌더링

위에서 render()를 통해 요청정보(request)template, 그리고 전달할 context를 인자로 전달하였다.

그러면 여기서 작성한 template를 불러와 화면이동이 가능한데 지금은 template도 만들지 않았다.

또한 template만 만든다고 연결되는 것이 아니라 설정을 추가해줘야한다.

➤ templates 폴더 생성

일단 현재 프로젝트 구조에서 templates 폴더를 생성해보자. 이제부터 여기에 모든 template 파일을 관리할 것이다.

.
├── README.md
├── config
│   ├── __init__.py
│   ├── __pycache__
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── db.sqlite3
├── manage.py
├── shortener
│   ├── __init__.py
│   ├── __pycache__
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   ├── models.py
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── templates 👈------------ 이거
│   └── index.html
└── venv

➤ settings.py 설정 추가

이제 views.py에서 render()에 전달한 template을 읽을 수 있게 설정을 추가해 보자.

📌 config/settings.py

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [],
        "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",
            ],
        },
    },
]

settings.py파일을 열어 TEMPLATES를 찾아가보자.

위와 같은 코드가 존재할 것이다. "DIRS"부분에 비어있는 리스트가 있을 것이다.

지금은 바라보는 템플릿이 없다는 뜻이다. 여기에 우리가 생성한 template을 바라볼 수 있게 설정을 추가하자.

"DIRS": [os.path.join(BASE_DIR, 'templates')],

위와 같이 추가를 해줘도 되고 따로 변수를 할당하여 아래와 같이 넣어 줘도 무관하다.

	TEMPLATES_DIR = [os.path.join(BASE_DIR, 'templates')]
    
	...
	...
	"DIRS": [TEMPLATES_DIR],
    ...
    ...

📌 templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Index Page</title>
</head>
<body>
    <h1>The is a Index Page</h1>
    <h3>{{ welcome_msg }}</h3>
    <span>{{ hello }}</span>
</body>
</html>

index.html파일을 생성 후 위의 코드를 작성하였다.


🔖 결과

url 라우팅과 view에서의 기능작성, template의 렌더링을 모두 작성하였다.

이제 장고를 시작한 후 브라우저에 요청 주소를 입력하여 보자.

python3 manage.py runserver

위와 같이 html파일에 작성한 내용과 view에서 ORM을 통해 조회한 사용자의 email주소가 화면에 렌더링 되면 성공이다.

🧑🏻‍💻 정리

  • 사용자(나)가 Browser를 통해 127.0.0.1/shortener 주소를 가진 요청을 웹 서버에 전달
  • 여기서 Django가 Web Server역할을 하며 urls.py에서 전달받은 요청 주소와 매칭되어 있는 view 기능을 찾아 전달
  • view에 작성된 기능(코드)들을 실행하며 template 렌더링
  • view에서 template에 렌더링한 context를 확인하여 노출되는 html화면에 표시
profile
인생 개발자 라곰!!

0개의 댓글