나는 각 유저를 위한 페이지 url 을 구성하고싶은 상황이다
users/spino/ ▷ 스피노 페이지
users/tyranno/ ▷ 티라노 페이지
하면 되는데
만약 유저가 백명이면?!
일일이 만들고 있을 생각하면 벌써 귀찮다
그럴때는 바뀌는 부분만 변수로 처리할 수 있다
users/변수/ ▷ 변수 페이지
이걸 Variable Routing 이라고 한다
URL 일부를 변수로 지정해서, 해당 부분에 들어온 값을 view로 넘겨줌
→ view에서 변수를 받아서 그 해당 부분에 맞게 처리
→ 하나의 URL에서 여러 페이지 연결 가능
▶ 직접 해보자 코드
view에서 username 매개변수 받아준 다음에 context 에 저장해서 넘겨주기
def profile(request, username):
context = {
"username": username,
}
return render(request, 'profile.html', context)
입력된 URL이 users/ 로 땡이면 views.users 로 넘겨서 처리하고,
users/ 뒤에 변수가 더 붙는다면 그걸 username 이라는 변수에 담아서 views.profile 로 넘기라는 뜻
users 템플릿은 기본페이지
profile 템플릿에서는 username 변수 받아서 보여주기
▶ 서버 실행 결과
기본 페이지
주소창에서 users 뒷부분을 수정했을때. 스피노 유저
이건 티라노 유저
▶ 변수타입
아 근데 urls.py 에서 변수를 쓸때
path('users/<username>/', views.profile),
이렇게 지정을 안해줄 경우 기본적으로 str 이 적용됨.
/ 빼고 나머지 문자열을 변수로 처리하겠다는 의미.
path('users/<str:username>/', views.profile),
그래도 헷갈리지 않게 str 명시해주기
path('users/<int:username>/', views.profile), # 숫자일때
숫자일경우. 즉 0또는 양의 정수를 변수로 처리하겠다는 의미
slug, uuid, path 등이 있는데 지금은 알기 귀찮다
str, int 만 써도 대부분 가능할거라고 하셧다.
▶ 하이퍼링크
<a> 앵커 태그와 href 속성으로 링크할 URL을 지정할 수 있다
# profile.html
{% extends 'base.html' %}
{% block content %}
<h1> {{ username }}의 프로필 페이지 </h1>
<h3> username : {{ username }} </h3>
<a href="/index/">Index 페이지로 돌아가기</a>
{% endblock content %}
하이퍼링크 누르면
인덱스 페이지로 넘어가진다 성공
multiple apps
하나의 프로젝트는 여러개의 앱으로 구성됨
근데 현재 하나의 url 안에 기능이 다들어잇다.
users 앱과 articles 앱을 분리해서 만들어보자.
[0] users 앱 생성 & 등록
python manage.py startapp users # 앱생성. 외워라
아 컴마 안찍었넹 다음부턴 까먹지말자
installed_apps 는 리스트 형태다
파이썬에서 리스트는 순서가 존재하는 자료형임
그래서 위에서부터 읽어들이기 때문에
장고가 만든 앱보다 사용자가 만든 앱을 위로 올려주는 게 더 권장되긴함
[1] 각 앱에 urls.py 만들기
urls.py 는 앱을 생성해도 장고에서 만들어주지 않는다. 왜지
따라서 내가 직접 articles 와 users 앱에 각각 urls.py 를 만들어준다.
urls.py 파일의 기본구조는 urlpatterns 임
[2] url 분리하기
my_first_pjt 에 우르르 몰려있는 url 경로들을 각 앱의 기능에 맞게 분리해준다.
users 앱의 urls 와 articles 앱의 urls 에게 각각 해당 경로를 옮겨주기
이렇게 분리를 해주고 나면 노랑밑줄이 남발하는것을 볼 수 있는데
장고가 말을 못알아먹고 있기 때문이다
path가 뭔데
views가 어디있는데
라고 하는중
path와 views 를 정의해준다.
path 정의는 장고한테서 가져오고 views 는 . 에서 가져와줌
. 이 뭔의미냐면 이 urls 파일이 있는 위치에서 views 를 찾으라는 뜻이다
지금 users/urls.py 를 보면 views.users 랑 views.profile 이 흰색인데
해당 urls 파일이 있는 위치(==users 폴더) 에서 views.users 랑 views.profile 를 찾을 수가 없기 때문.
왜냐면 내가 지금까지 articles 폴더에서 작업했으니까 articles 폴더의 views 에 다 들어있음
따라서 users/urls.py 에서는 from articles import views 라고 불러와주는 게 맞다.
근데 그렇게 하면 앱을 분리하는 의미가 없겠지?
그래서 articles 폴더의 views 에 있는 기능들 중에
users 에 해당하는 기능들을 users/views로 옮겨와 준다
[3] views 분리하기
views.py 는 앱을 생성할 때 장고가 자동으로 만들어준다. 물론 비어있다
현재상태. articles 폴더의 views 에 기능이 전부 들어있음.
users 에 해당하는 기능(함수)은 users 폴더의 views 로 옮겨주자
users 함수랑 profile 함수만 옮겨줬음
근데 사실 장고로 request 가 들어오면 project 의 urls 로 req가 들어온다.
그래서 users/urls랑 articles/urls 를 project/urls 로 포함시켜 주는 작업이 필요하다
[4] urls 포함시키기
처음 request 가 들어올 프로젝트 폴더의 urls.py 파일
include 함수는 장고.urls 안에 있다. 불러와줌
그리고 path 경로 설정 해줌
ex) users/dino/ 가 들어왔을때
line22~ line24 : 일치하는 게 없으니 지나감
line25 : users/ 일치하니까 그 뒷부분은 users.urls 로 넘어감
그럼 dino/ 만 넘어가겠지?
어디로 넘어가냐면 앞부분이 users였으니 users 앱의 urls 로 넘어간다
넘어온 dino/는 users/urls.py 에서 경로를 비교하게 되는데,
현재 path에 users/dino/를 원하고있기 때문에 dino/랑 일치하는게 없다. 에러
수정코드
urlpatterns =[
path('', views.users),
path('<str:username>/', views.profile),
# 앞부분(users/)는 프로젝트 폴더에서 처리하니까 없애줌
]
따라서 프로젝트폴더에서 미리 처리된 앞부분(users/)은 없애버리기
근데 만약에 users/profile/dino 가 들어온다면?!
users/dino/payment 가 들어온다면?
일치하는 패턴이 없으니 또 Page not found (404) 화면을 보게 될 것임.
따라서
urlpatterns =[
path('', views.users),
path('profile/<str:username>/', views.profile),
]
앞으로는 이런식으로 해당 패턴에 맞게 경로를 구체화 시켜줘야된다
여기까지 views 와 urls를 모두 분리해줬음
이런식으로 앱기능 분리하기 끝!!!
아직 끝 아니엇음..
완벽한 분리를 위해 templates(html파일들)도 분리해보자
[5] templates 분리하기
users 앱에 templates 폴더를 생성해주고
articles 앱의 templates 에서 user 기능에 해당하는 html 파일을 드래그앤드롭으로 옮겨와준다
사진은 없다 귀찬기 때문
profile.html 이랑 users.html 파일을 옮겨와 줬다
[6] 진짜 끝! 실행해보기
python manage.py runserver # 서버실행. 좀외워라
주소창에 직접 입력 바꿔보면서 확인완료 좋아 잘 되는군
근데 여기서 데이터를 전송해보면
또 page not found...
이유는
data-throw 페이지에서 data-catch/ 로 데이터를 전송하고 있는데
앱의 기능을 분리하면서 articles/data-catch/ 로 보내는걸로 바꼇기 때문
따라서 경로를 바꿔준다
수정코드
<form action="/articles/data-catch/" method="GET">
# 경로에 articles/ 추가
이제 catch 페이지 정상 동작함!
근데 여기서 저 하이퍼링크를 누르면
후...
그렇다 data-throw 도 articles 를 추가해줘야된다
수정코드
<a href="/articles/data-throw/">데이터 또 입력하러 가기!!!</a>
그럼 하이퍼링크도 정상작동함!
근데 지금은 예시라서 페이지가 2개지만
만약 실제 프젝을 한다고 가정햇을때는
어떤 url 경로를 바꿀 때 엄청 많은 경로를 하나씩 찾아가면서 다 바꿔야됨
그와중에 오타라도 잇으면 오류가 나게됨
나는야 상습오타범으로서 하드코딩은 피하고싶다
그래서 장고가 제공하는 게 있음!
바로 각각의 url 들에게 '별명'을 붙여주는거다
먼소리야
[7] 경로에 별명 붙이기
이렇게 name 을 붙여주면
나중에 view에서사용하건 template 에서 사용하든
어디의 어떤 경로인지 대신에 name 만 가져다가 쓸 수 있게 된다.
이제 이 name 을 templates 에서 사용하면된다
사용하는 방법 !
url 템플릿 태그를 사용한다.
{% url 'url_name' %} # 템플릿 태그
이렇게 햇을때 좋은점?
만약 나중에 내가 경로 이름을 수정하고 싶을때
예를들면 urls.py 파일에서 경로를 data-throw → throw 로 변경해도 name 은 data-throw 로 유지되니깐
템플릿에서 data-throw 가 사용된 부분을 수정하지 않아도 된다.
일일이 찾아서 throw로 바꿔주고 싶다면 사용안해도 된다
[7-2] data-throw 에서 홈(index)으로 바로 가는 링크 만들기
위의 data-throw.html 파일에다가 링크추가
# articles/templates/data_throw.html
<a href="/index/">INDEX로 가기!!!!!</a> # 앵커태그 추가
이렇게 /index/ 를 명시해주면 되는데
하드코딩 하지 말고 방금 배운 name 을 사용해보면
프로젝트 폴더의 urls.py 파일에서 index 경로에 name 을 지정해주면
# articles/templates/data_throw.html
<a href="{% url 'index' %}">INDEX로 가기!!!!!</a> # url 템플릿태그로 대체가능
이렇게 url 태그를 사용할 수 있다
하이퍼링크 누르면
헤헤 정상작동 확인
[7-3] index 페이지에 각각으로 이동하는 링크 만들기
users 앱의 urls 에도 각각 name 지정해주고
index 템플릿에서 링크 걸어주기
<br> 은 줄바꿈 해주는거다. break 약자인듯
야호
이런식으로 여기저기로 이동하는 링크를 만들 때 name 지정과 url 템플릿 태그를 사용해서
하드코딩하지 않고 특정 경로에 대한 의존성을 제거할 수 있다
'Django' 카테고리의 다른 글
[Django] 시험 오답노트 (1) | 2024.09.02 |
---|---|
[Django] #11 장고 Model (0) | 2024.08.16 |
[Django] #9 HTTP Form (0) | 2024.08.15 |
[Django] #8 장고 Template System (0) | 2024.08.14 |
[Django] #7 장고 Template 시작하기 (0) | 2024.08.13 |