본문 바로가기

매일 TIL

[내일배움캠프 8-1일] HTML form, Variable Routing, Multiple Apps, Naming URL Patterns

HTTP form

{% extends 'base.html' %}

{% block content %}
    <h1>Data Throw</h1>

    <form action="" method="GET">

        <label for="message">데이터 입력 </label>
        <input type="text" id="message" name="message">

        <button type="submit">전송</button>

    </form>
{% endblock content %}

lable의 for는 input의 id와 동일해야 함.

input 에서 핵심 속성은 name
name 이 있어야 데이터를 전달할 수 있다.
name 으로 서버에 데이터를 전달하고, 서버는 name 을 보고 데이터를 판단하는 것.

 

method의 GET 방식은 쿼리스트링을 사용해서 데이터를 서버로 전송.

쿼리스트링이란 url에 데이터가 포함되어 전송되는 방법.

URL을 확인해보면 ?뒤에 데이터가 위치한 것을 알 수 있다.

key = value 형태로 구성됨.

여기서 key는 우리가 name에서 정의한 "message"가 되고, value는 우리가 입력한 123123


입력한 데이터를 저장하고 표시하는 다른 경로를 만들고 싶다면?

def data_catch(request):
    message = request.GET.get('message')
    context = {'message': message}
    return render(request, 'data_catch.html', context)

data_catch를 만들면 된다.

request.GET을 사용.

{% extends 'base.html' %}

{% block content %}
    <h1>Data Catch</h1>

    <h3>Current Data</h3>
    <p>Current data is: {{ message }}</p>

    <a href="/data-throw/">데이터 던지러 가기!</a>

{% endblock content %}

message 변수를 사용하여 data-catch 페이지에 표시.

<a></a>를 사용해 하이퍼링크를 걸어줌.

눌러서 바로 다시 data-throw로 갈 수 있도록.

{% extends 'base.html' %}

{% block content %}
    <h1>Data Throw</h1>

    <form action="/data-catch/" method="GET">

        <label for="message">데이터 입력 </label>
        <input type="text" id="message" name="message">

        <button type="submit">전송</button>

    </form>
{% endblock content %}

action에 경로를 입력하여 data-catch에 데이터를 저장.


Variable Routing

예를 들어 유저 프로필 페이지를 만든다고 했을 때,

users/aiden/ 이면 에이든의 페이지로, users/tmoon/ 하면 티문 페이지로 가면 좋을텐데,

그러면 사람이 추가될 때마다 urls, views, html생성 전부 해줘야 할까? -> 아니다.

    path('users/', views.users),
    path('users/<username>/', views.profile),

users/로 끝난다면 users뷰를 처리.

users/이름/ 이라면 profile 뷰로 변수 username을 보내서 처리.

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

profile 뷰는 들어오는 변수 username을 받을 수 있어야 함.

즉 request 뿐만 아니라 username 파라미터가 필요.

{% extends 'base.html' %}

{% block content %}
    <h1>{{ username }} Profile Page</h1>
{% endblock content %}

profile.html에서 변수로 사용.


Multiple Apps(앱 두개 됨)

우선 users 앱 생성, 등록.

이러면 이제 articlesusers 두개의 앱이 존재.

urls를 각 앱에 맞춰 작성하고 싶기 때문에, 앱 안에 각각 urls를 만들어준다.

앱 각각 urls.py을 생성한다는 것.

from django.urls import path
from . import views

urlpatterns = [
    path('hello/', views.hello),
    path('data-throw/', views.data_throw),
    path('data-catch/', views.data_catch),
]

articles 앱의 urls.py

urls.py가 있는 지금 내 위치에서 views.py를 import하라는 것.

from django.urls import path
from . import views

urlpatterns = [
    path('users/', views.users),
    path('users/<str:username>/', views.profile),
]

users 앱의 urls.py도 마찬가지로 처리

 

다 좋은데 끝난 것은 아니다.

request가 들어오면 articles나 users의 urls에서 처리하는 것이 아닌 my_first_pjt의 urls를 참조하여 처리한다.

그렇기 때문에 my_first_pjt의 urls에서 나머지 둘의 urls를 포함시켜 주어야 함.

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', views.index),
    path('articles/', include('articles.urls')),
    path('users/', include('users.urls')),
]

include를 사용하여 둘의 url을 포함시켜준다.

 

자, 이상태로 만약 users/aiden이라는 주소가 들어온다면 어떻게 될까?

우선 my_first_pjt의 urls에서 처리됨. 여기서 users/이기 때문에 users.urls로 이동하여 마저 처리가 되는데,

이때 중요한 것은 users/aiden 중 users는 처리한 상태로 aiden만 이동하게 되는것.

즉 users 앱의 urls는 aiden만 들어오게 되고 해당 경로가 없기 때문에 오류가 나게 된다.

1-11강의 35:20 설명 참고

대충 이런 원리로 이해하면 된다.


Naming URL Patterns(경로에 별명 붙이기)

from django.urls import path
from . import views

urlpatterns = [
    path('hello/', views.hello, name='hello'),
    path('data-throw/', views.data_throw, name='data-throw'),
    path('data-catch/', views.data_catch, name='data-catch'),
]

urls에서 name='별명 이름' 을 정할 수 있음.

html에서 경로를 직접 입력하지 않고 별병으로 처리할 수 있다.

{% extends 'base.html' %}

{% block content %}
    <h1>Data Throw</h1>

    <form action="{% url 'data-catch' %}" method="GET">

        <label for="message">데이터 입력 </label>
        <input type="text" id="message" name="message">

        <button type="submit">전송</button>

    </form>
{% endblock content %}

사용할 때는 경로가 들어갈 자리에 템플릿 태그 형태로 사용하면 됨.

data_throw.html에서 /articles/data-catch/ 대신 {% url 'data-catch %}을 사용한 예시.


웹 요청 과정

A : 클라이언트가 브라우저에 URL을 입력

B : 브라우저는 사용자가 입력한 도메인 주소를 DNS 서버에 보냄.

C, D : DB에서 필요한 정보를 얻음.(도메인 주소에 매핑된 ip 주소)

E : ip 주소를 브라우저로 반환.

F : 브라우저가 해당 웹 서버로 요청을 보냄.(HTTP/HTTPS 요청)

G, H : DB에서 필요한 정보를 얻음.

I : 웹 서버가 브라우저로 데이터를 반환.(HTML, CSS, JavaScript)

J : 브라우저는 이쁘게 랜더링하여 클라이언트에게 보여줌.


오늘의 회고

할게 꽤나 많았다.

강의 진도 빼고, 웹 특강 듣고, 스쿼드 강의 듣고 하느라 월요일부터 바빴다.

진도 더 빼고 싶었는데 아쉽...

 

내일의 목표는 강의 1-15까지 듣기 + 웹 특강 듣기