Lina's Toolbox

Django 의 다중앱과 URL 본문

스파르타 내일 배움 캠프 AI 웹개발 과정/Django framework

Django 의 다중앱과 URL

Woolina 2024. 8. 16. 01:46

 

Django URLs

URL dispatcher

공식 문서: https://docs.djangoproject.com/en/4.2/topics/http/urls/#top

 

🔽 Dispatcher란 무엇일까요?

더보기
  • 응급 콜센터에서 상주하는 사람
  • 작업을 관리하는 구성요소
  • 택배 운송 경로를 계획하는 직원
  • 무언가를 목적지로 보내는 주체라고 이해할 수 있겠습니다.

저희는 지금 웹을 배우고 있으니 우리 식으로 해석을 해보면 이렇습니다!

💡 Dispatcher 들어온 요청을 어디로 보내서 처리할지 정하는 곳!

 

 

/ 이야기

  • https://www.mycooooolsite.com/
  • https://www.mycooooolsite.com
💡 이 두개는 다른 겁니다.

https://www.mycooooolsite.com/   (디렉토리)
https://www.mycooooolsite.com    (파일)

원래는 이런 의미를 가지고 있는데,
사실 오늘날에는 (사람들이) 같은 것으로 인식하고 있는 경우가 많습니다.

 

트레일링 슬래시(Trailing slash)

  • 개념 자체는 URL 뒤에 붙는 슬래시입니다.
  • 그런데 이게 우리들에게 자꾸 회자되는 이유는 컴퓨터들 사이에서는 저 두 개는 다른것이기때문입니다!
💡 어떻게 다를까요?

/가 붙으면 이건 디렉토리라는 의미를 가집니다.
/ 가 붙었다 → 아 디렉토리 구나 → 안쪽에서 필요한 파일을 찾고 → 접근
/없다파일이구나 → 접근


/ 붙이는게 특정 리소스에 접근하는데 속도측면에서 약~~~~간 더 이득이 있긴한데 큰 차이가 나는 것은 아닙니다.

그래서요?🧐
선택의 문제라는 겁니다.
우리 서버에서는 그럼 어떤것을 기준으로 처리할지 정하면 되는 문제입니다!

about 으로 들어오면 about/ 으로 처리할지
about/ 으로 들어오면 about 으로 처리할지
→ django는 기본적으로 1번을 선택했고, 이 옵션은 바꿀 수 있습니다.
그러나 굳이 바꿀 이유가 없기 때문에 그대로 진행하겠습니다!

 

원래 url은 path 가 반드시 있어야합니다.

그런데 google.com 같은 경우 없죠? →  누군가 저걸 입력하면 / 를 붙여서 요청하는 것입니다. ( 이것을 웹브라우저가 해줍니다! )

 

 

 

aiden 유저와 tmoon 유저의 프로필 페이지를 위한 url을 구성해보자,

  • users/aiden/ → 에이든 페이지
  • users/tmoon/ → 티문 페이지

구현

 

❓ 만약 유저가 100명이라면 어떻게 해야할까요?

  • 유저의 이름에 따라 각기 다른 path()코드 100줄과… html파일 100개…

→ 너무 힘들고 비효율적일 것입니다.
어차피 앞의 users/경로는 동일하고 뒤에 오는 유저 이름만 바뀌는데 이 걸 활용할 수 있는 방법이 있을까요?

  • 바뀌는 부분만 변수로 처리하는 식으로 …
    users/변수/ 이렇게요!

 

Variable Routing

  • URL 일부를 변수로 지정하여, 해당 부분에 들어온 값을 view로 넘겨줄 수 있습니다.
  • view에서 변수를 받아서 그 부분에 맞게 처리하도록 할 수 있습니다.
    → 하나의 URL에 마음껏 여러 페이지 연결할 수 있겠죠?

urls.py

path("users/<str:username>/", views.profile),

 

 

views.py

def profile(request):
		return render(request, "profile.html")

request:  장고로 요청이 들어오면 장고가 Httprequest  객체를 만들어서,  그 객체를 view의 첫번째 인자로 전달해준다. 

VScode 단축키

위에서 아래로 작성한 여러줄의 코드에서 코드순서를 바꾸고 싶을 때가 있죠?
그럴 때 순서를 바꾸고 싶은 코드라인을 클릭해서 커서를 두고 다음과 같이 하면 됩니다!

  • Windows: alt + 위, 아래 방향키
  • macOS: option + 위, 아래 방향키

 

 

View 완성하기

/<username>/ -> username도 뷰의 인자로 전달해줄수 있다.

아무것도 안적어줄경우 디폴트는 str로 처리됨

 

str:username

int:username

String 이여도 이런식으로 명시해주면 더 좋다.

 

  • 이런 애들이 가능해요
    • str
      • 기본값
      • / 빼고 나머지 문자열을 변수로 처리
    • int
      • 0 또는 양의 정수를 변수로 처리
    • slug
    • uuid
    • patht

 

실습

variable routing을 이용해서 /users/유저네임/ 으로 들어오면 profile.html 을 사용해서 아래의 페이지가 보여지도록 해주세요.

홈 == index 페이지

 

urls.py

path("users/<str:username>/", views.profile),

 

views.py

def profile(request, username):
		context = {
				"username" : username,
		}
		return render(request, "profile.html", context)

 

profile.html

{% extends "base.html" %}

{% block content %}
		<h1>{{ username }}의 프로필 페이지</h1>
		
		<div>
			<h2>username : {{ username }}</h2>
		</div>
		
		<a href="/index/">홈으로 돌아가기</a>
		
{% endblock content %}

 


Multiple Apps

 

 ✔️ 앞에서 살펴본 것과 같이 새로운 종류의 경로가 추가될 때 users면 users끼리 post면 post끼리 묶어서 관리하는 방법은 없을까요?

 

 

하나의 프로젝트는 여러개의 앱으로 구성됨

 

계속 이런식으로 하다보면 urls.py에 엄청나게 많은 url이 들어갈 것입니다.

각각의 기능별로 나누어서 App으로 분리하는 것이 좋은 구조입니다.

 

 

users 앱 생성

users 앱을 생성하고 등록해 주세요.

 

(지금 실행중인 서버가 있다면 끄고 진행)

python3 manage.py startapp users

 

setting.py가서 installed_apps에 "users", 추가해준다.

리스트는  "순서"가 있는 자료형이기 때문에,

장고가 직접만든 앱들 ("django.~ ") 을 사용자가 직접만든 앱("articles","users",)들 보다 위로 올려주는 구조를 권장한다.

(장고 내장앱 ➡️ 써드파티 앱 ➡️ 내가 만든 앱 순서.)

 

App이 많아진다면 각각의 app안에 views가 생기고 …

urls도 복잡해질텐데?

지금은 하나의 urls.py만 사용중이죠?

App마다 urls.py를  분리하자

보통 대부분의 개발자들이 장고로 개발을 할때는
이렇게 앱마다 urls.py를 분리하여 개발합니다.

 

 

Urls 분리하기

django가 기본적으로 생성해주지 않기 때문에 직접 생성해주어야합니다.

 

각각의 app 폴더 안쪽에 urls.py 이름으로 파일 생성

# urls.py 

from django.urls import path

urlpatterns = [
    
]

 

 

다른 URLconf 모듈을 포함하기 (include)

  • django의 urls는 다른 urls를 포함할 수 있습니다.
  • 프로젝트의 urls에 include를 통해 우리가 분리한 app의 경로를 포함시켜줍니다.

 

urls 연결하기

from django.urls.conf import include

from django.urls import path,include 처럼 기존 코드에서 include를 추가하는 것도 역시 괜찮습니다.

 

urlpatterns

path("articles/", include("articles.urls")),
path("users/", include("users.urls")),

  • include되는 urls에는 반드시 urlpatterns 가 필요 (빈 리스트이더라도 있어야합니다!)
  • 이제 articles/test/ 로 요청이 들어오면 아래의 흐름을 따르게 됩니다.
    1. 프로젝트의 urls.py 에서 articles/ 패턴과 일치함을 발견
    2. articles 앱의 urls.py로 다음 처리를 이관
    3. articles앱의 urls.py에서 test/ 패턴과 일치하는 url 패턴을 탐색
    4. 일치하면 해당 views로 가서 처리
맨 처음에 프로젝트의 urls.py로 도착함.→ 프로젝트의 urls를 보면서 처리함
path("articles/", include("articles.urls")) → articles/를 포함하여 articles.urls로 넘기겠다!  (/test/을 넘긴다.)

 

 

📌 해당하는 urlpatterns 긁어오면, 에러가 발생합니다.

"path" is not defined

"views" is not defined

from django.urls import path
from . import views

 

import해주면 해결됩니다.

.  :  내 위치 (urls.py가 있는 위치와 같은 위치)

 

 

url 수정하기

(users)urls.py

path("", views.users),
path("profile/<str:username>/", views.profile),

users의 urls.py에서는 users/가 더이상 필요없다! → 지워준다.
(안지워주면 users/users/adien이 됨. )
즉 users/는 (프로젝트의 urls.py)에서 이미 처리되고 온 것이므로 지워주자.

그냥 요청이 user/ 였으면, 프로젝트 urls.py에서 처리된 후 넘어온 값은 ""일것

🚨 하지만! 만약 users/profile/aiden/aiden/같은게 넘어온다면?
에러난다.
users/profile/aiden/까지만 처리해줬다.
뒤에 하나가 더 있는 패턴은 뷰를 아직 지정안했다.

 

아직은 에러가 나서 서버를 실행할 수 없습니다. views도 옮겨줘야 합니다.

 

 

views 옮기기

각 App에 맞게 view를 옮겨줍니다.

 

 

templates 옮기기

  • users앱에도 templates 디렉토리를 생성하고 필요한 template을 옮겨주자!

 

Q. 만약 지금 hello/ 로 접근하면 어떻게 될까요?

에러가  뜬다면 아래서부터 읽으며 해결하자!

이제 더이상 하나의 앱이 아님

-> /data_catch/"가 아닌 "/articles/data_catch/"가 되어야함

 

-> 지금은 2개밖에 안바꿔줬지만

실제의 프로덕트라면...?

 

몇십개 파일 하나하나 경로를 다 찾아 바꿔줘야할것.

귀찮고 오타나서 에러날 위험성도 높다.

💡 에러 ! 왜?

  • 이전에 hello/ 가 지금은 articles/hello/ 로 바뀌었기 때문입니다.
  • 이거야 우리가 바꿔주면 되지만 …
  • 이렇게 매번 url을 다 바꿔야한다면?
    → 너무 바꿔야할 것이 많아지는데요…
    → 뭔가 이름을 지정해서 내용이 바뀌더라도 이름으로 부르도록 하면 좋지 않을까요…? 🤔

 

Naming URL Patterns

  • 어떠한 URL을 작성할 때 직접 하드코딩 하지 않고 각각의 URL에 ‘이름’을 붙여주는 것을 말합니다.
  • view와 template에서 특정 경로에 대한 의존성을 제거할 수 있습니다. (위와 같은말입니다.)

path() 함수의 name 파라미터 사용

 urls.py 에서 각각 name=""를 붙여서 url에 name을 붙여줄 수있다.

 

 

URL이름 사용하기

  • 이제 직접 URL을 하드코딩 하지 않아도 된다!
    * 하드코딩: 내가 필요한 데이터를 변수에 참조하는 형태가 아닌 그대로 적어주는 형태

원래는 이렇게 직접 모든 URL을 적었다면
이제는 URL을 이름으로 참조할 수 있습니다.

템플릿에서 {% url 'name' %}을 해준다.

→ 이렇게 하면 뭐가좋은건가요?

나중에 urls.py 에서 수정해줘도 템플릿 코드를 수정하지 않아도 된다!

 

 

index.html에 여러가지 링크를 만들어주자

index.html

<ul>
	<li><a href="{% url 'hello' %}">Hello</a></li>
	<li><a href="{% url 'throw' %}">Throw</a></li>
</ul>

다른 페이지에도 필요한곳에 만들어주면 되겠죠 👀


'스파르타 내일 배움 캠프 AI 웹개발 과정 > Django framework' 카테고리의 다른 글

Django ORM  (0) 2024.08.27
Django Model  (0) 2024.08.20
Django의 HTML form  (0) 2024.08.16
Django Template System  (0) 2024.08.15
Django Template 시작하기  (0) 2024.08.12