# Django Template & View & URL

## template과 view

앞선 [Django View & URL (2)](https://dahye-jeong.gitbook.io/til/django/basic/2019-03-08-url)에서는 View에서 페이지의 디자인을 하드코딩 하고 있는 문제점이 있었다. 이제 template을 생성했으므로 view를 update해볼것이다.

```python
# polls/views.py
from django.http import HttpResponse
from django.template import loader
from .models import Question

def index(request):
    last_question_list = Question.objects.order_by('-pub_date')[:5]
    # polls/index.html 템플릿 가져오기
  template = loader.get_template('polls/index.html')
    # template에서 쓰이는 변수명과, python 객체를 연결하는 dictionary
  context = {
        'last_question_list': last_question_list,
    }
  # context 전달하기
    return HttpResponse(template.render(context,request))
```

### render()

template에 context를 전달해 표현한 결과를 HttpResponse객체와 함께 return해주는 구문은 자주쓰는 용법이다. Django는 이를 쉽게 표현할 수 있게 단축기능을 제공해준다.

```python
from django.shortcuts import render
from .models import Question

def index(request):
    last_question_list = Question.objects.order_by('-pub_date')[:5]
    context = {
        'last_question_list': last_question_list,
    }
    return render(request, 'polls/index.html', context)
```

`loader`와 `HttpResponse` 를 더 이상 import하지 않아도 된다.

```python
render(request, template_name, context=None, content_type=None, status=None, using=None)
```

render함수는 request, template\_name을 첫번째, 두번째 인수로 받으며, 다음부터는 선택적(optional)인수로 받는다. render함수는 인수로 지정된 context로 표현된 template의 **HttpResponse**객체가 반환된다.

## 404 Error

```python
from django.shortcuts import render
from django.http import Http404

def detail(request, question_id):
    try:
        question = Question.objects.get(pk=question_id)
    except Question.DoesNotExist:
        raise Http404("Question does not exist")
    return render(request, 'polls/detail.html', {'question': question})
```

`http://127.0.0.1:8000/polls/1/` 로 접속해보면 아래와 같은 오류가 발생하는 것을 볼 수 있다.

![image-20190311115921508](https://3919143544-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M26jG1uJ-xuMP0XPOri%2F-M26jI7aMnfiDMQcEU0Y%2F-M26jUjR4wuNPy8YNL9f%2Fimage-20190311115921508.png?generation=1583899102664244\&alt=media)

템플릿이 존재하지 않는다는 오류이다.

`polls/templates/polls` 디렉토리 하위에 `detail.html` 템플릿을 생성해주고 난 후 새로고침을 하면 오류가 안나는 것을 확인 할 수 있다.

### get\_object\_or\_404()

객체가 존재하지 않을 때 `get()`을 이용하여 Http404예외를 발생시키는 것은 자주 발생한다. 위의 `render()` 처럼 Django에서 단축기능을 제공해준다.

```python
from django.shortcuts import get_object_or_404, render

def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/detail.html', {'question': question})
```

## URL

template에서 하드코딩된 url을 \`

\` 을 사용하여 의존성을 제거할 수 있다.

```python
# urls.py
# the 'name' value as called by the {% url %} template tag
urlpatterns = [
    path('', views.index, name='index'),
    path('<int:question_id>/',views.detail, name='detail'),
    path('<int:question_id>/results/',views.results, name='results'),
    path('<int:question_id>/vote/',views.vote, name='vote'),
]
```

여기서 name을 template tag \`

\`에서 호출할 때 부르는 이름이다.

```markup
{# template #}
{% for question in last_question_list %}
    <li><a href="/polls/{{question.id}}/">{{ question.question_text}}</a></li>
{% endfor %}
```

다음과 같이 하드코딩된 부분을 아래와 같이 변경할 수 있다.

```markup
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
```

하지만 project에 여러개의 app이 존재하고, 같은 path name을 가지고 있을 수 있다. **URLconf**에 namespace를 추가 함으로써 해결할 수 있다.

```python
# polls/urls.py
from django.urls import path

from . import views

app_name = 'polls'
urlpatterns = [
    path('', views.index, name='index'),
    path('<int:question_id>/',views.detail, name='detail'),
    path('<int:question_id>/results/',views.results, name='results'),
    path('<int:question_id>/vote/',views.vote, name='vote'),
]
```

```markup
{# polls/index.html #}
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text}}</a></li>
```

## 참조

* [Django shortcut functions](https://docs.djangoproject.com/ko/2.1/topics/http/shortcuts/#module-django.shortcuts)
* [Django tutorials](https://docs.djangoproject.com/ko/2.1/intro/tutorial03/)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dahye-jeong.gitbook.io/til/django/basic/2019-03-11-mvc.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
