본문으로 바로가기

url과 view(FBV), django templates

category Django, Flask/🔫 Django 2020. 6. 14. 00:39

🚀 django URL 구성

 

 

일반적으로, python manage.py startapp [원하는 이름]로 앱을 생성한 후 views.py에 가서 view 관련 코드를 작성한 후,

config/urls.py에 등록해주는 방식으로 url와 view를 결합시킨다.

 

그런데 이런 방식은 url의 층위가 깊어질수록 관리하기 힘들어진다.

 

따라서 app 차원에서 별도로 urls.py를 생성해서 app 별로 url을 관리한 후 config/urls.py에 등록하는 방식으로 divided and conquer를 한다. 단, globalRouter는 core/urls.py에서 관리하도록 처리하자.

 

🚀뭔 소리야?
view 모델 정의 -> app 단위 urls.py에 등록 -> config/urls.py에 등록

 

우선 사용하고 싶은 views를 정의합니다. 브라우저에서 url로 이동하면 django에게 req를 날립니다.

이 req는 view에서 정의한 함수의 첫번째 인자로 들어갑니다.

이 req에는 is_auth, is_axax등 유용한 메서드가 많습니다. 나중에 사용해봅시다.

(https://docs.djangoproject.com/en/3.0/ref/request-response/)

 

한편, req를 받아 로직을 처리하는 view 함수에서는 이 적절한 res(HttpResponse object)를 돌려줘야 합니다. 

# rooms/views.py
from django.http import HttpResponse

# Create your views here.
def all_rooms(req):
    return HttpResponse(content="<h1>Hello</h1>")

 

정의한 view 함수를 적절한 app/urls.py에 넣어줍니다.

여기서 app_name은 config/urls.py에 지정한 namespace와 같은 이름이어야 합니다.

 

그래야 config/urls.py와 app 단위에 정의한 urls.py가 연결되겠죠~

"" 는 아무것도 없는 /을 의미합니다.

 

# core/urls.py

from django.urls import path
from rooms import views as room_views

app_name = "core"

urlpatterns = [
    path("", room_views.all_rooms, name="home"),
]

 

config/urls.py에 생성한 urls.py를 urlpatterns에 포함시켜줍니다. namespace가 위에ㅐ서 작성한 app_name과 동일한 core인 것을 보실 수 있습니다.

# config/urls.py

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path("", include("core.urls", namespace="core"),),
    path("admin/", admin.site.urls),
]

 

위의 경우 / 와 /admin을 받게 됩니다.

 

url에 다른 새로운 것을 넣기 위해서는 위와 똑같은 과정을 거치면 됩니다.

view 모델 정의 -> app 단위 urls.py에 등록 -> config/urls.py에 등록

def room_detail(request):

    return render(request, "rooms/detail.html")
from django.urls import path
from . import views as room_views

app_name = "rooms"

urlpatterns = [
    path("1", room_views.room_detail, name="detail"),
]

 

urlpatterns = [
    path("", include("core.urls", namespace="core"),),
    path("rooms/", include("rooms.urls", namespace="rooms")),
    path("admin/", admin.site.urls),
]

 

이 결과 /, /rooms/1, /admin을 받게 됩니다.

 

 

결국 아래와 같을 꼴로 정리하게 되는 셈입니다.

 


🚀 django template

Express에서 했던 것처럼, django도 HttpResponse를 직접 받아서 화면을 렌더링하기 보다 뷰 엔진 템플릿을 받아서 render하는 경우가 많습니다. 더 동적이고 편리하기 때문입니다. 

 

django는 자체적인 Template Engine을 사용합니다. 사용합니다. flask에서 사용하는 Jinja2와 사용법이 비슷합니다.

 

config/settings.py에 가서 DIR 키의 값으로 templates의 경로를 알려줍시다. 저는 최상위에 templates라는 이름의 폴더를 만들고 그곳에서 html을 생성할 것이므로 다음과 같이 등록해주었습니다.

# config/settings.py

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [os.path.join(BASE_DIR, "templates")],
        "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",
            ],
        },
    },
]

 

render(req, 템플릿, 템플릿에 전달할 변수(context))

from datetime import datetime
from django.shortcuts import render

# Create your views here.
def all_rooms(req):
    now = datetime.now()
    return render(req, "all_rooms.html", context={"now": now, "hungry": True})

 

 

사용법은 다음과 같습니다.

<h1>Hello</h1>
<h3>the time is {{now}}</h3>
<div>
  {% if hungry == True %}
   I'm hungry
  {% else %}
    I'm not hungry\
  {% endif %}
</div>

 

주의할 점은 템플릿 내에 함수를 실행할 때 독특하게 () 을 붙이지 않아도 실행된다는 것입니다.

 

보통 room.amenities.all()로 결과물을 불러오지만 템플릿 내에서는 ()를 붙이지 않아도 실행됩니다.

오히려 () 붙이면 작동하지 않습니다.

{% for a in room.amenities.all %}
    <li>{{a}}</li>
{% endfor %}

 


템플릿 내에서 사용할 수 있는 연산이나 로직은 아래에 정리되어 있습니다.

템플릿 내에서는 +-*/ 가 불가능합니다~ 대신 add 필터 등을 사용합니다.

 

https://docs.djangoproject.com/en/3.0/ref/templates/builtins/

 

Built-in template tags and filters | Django documentation | Django

The Django Software Foundation deeply values the diversity of our developers, users, and community. We are distraught by the suffering, oppression, and systemic racism the Black community faces every day. We can no longer remain silent. In silence, we are

docs.djangoproject.com

🚀 extends와 block, include

 

extends는 말 그대로 가능 기저 html를 연장하는데 사용합니다.

block은 특정 내용을 넣기 위한 창입니다. {% block [이름] %}{% endblock %} 으로 활용하시면 됩니다.

 

사용 방법을 보시면 pug와 같은 뷰 엔진과 사용법이 비슷한 것을 느끼실 수 있습니다.

# templates/base.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>{% block page_name%} {% endblock page_name%} | Airbnb</title>
  </head>
  <body>
    {% block content %} {% endblock %} &copy; airbnb
  </body>
</html>
<!-- base -->

extends를 활용해서 base.html을 연장해서 사용합니다.
{% extends "base.html" %}

<!-- pagename block -->
block을 활용
{% block page_name%} Home {% endblock page_name%}

<!-- block-->
{% block content %}
	{% for room in rooms%}
		<h2>{{room.name}} / ${{room.price}}</h2>	
	{%endfor%}
{% endblock %}

 

한편, include는 단순히 무언가를 가져올 뿐입니다. 동적으로 바뀌지 않는 내용을 include로 가져오는 것이 좋습니다.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>{% block page_name%} {% endblock page_name%} | Airbnb</title>
  </head>
  <body>

    {% include "partials/header.html"%}

    {% block content %} {% endblock %}
    
    {% include "partials/footer.html"%}
  </body>
</html>

darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체