# Django View & URL (2)

장고는 `URLconf`(URL configuration)을 사용한다. `URLconf` 는 URL 패턴을 views에 연결한다. 이전에 [Django View 와 URL (1)](https://dahye-jeong.gitbook.io/django/basic/2019-03-06-view)에서 url을 잠깐 다룬적이 있다. 이 장에서 더 자세히 살펴볼 것이다.

## View와 URL

### views.py

```python
# app/views.py
from django.http import HttpResponse


def index(request):
    return HttpResponse("<h1>Hello, world</h1>")

def detail(request, question_id):
    return HttpResponse("You're looking at question %s" % question_id)

def results(request, question_id):
    response = "You're looking at the results %s"
    return HttpResponse(response % question_id)

def vote(request, question_id):
    return HttpResponse("You're voting on question %s" % question_id)
```

### urls.py

```python
from django.urls import path

from . import views

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'),
]
```

다음과 같이 view와 url을 연결할 수 있다.

`http://localhost:8000/polls`, `http://localhost:8000/polls/1`, `http://localhost:8000/polls/1/results`, `http://localhost:8000/polls/1/vote` 와 같은 url로 view에 접근할 수 있다.

다음과 같이 사용자가 웹사이트의 페이지를 요청하면 Django는 `mysite.urls`(project.urls) 파이썬 모듈을 불러온다. 거기서 **urlpatterns** 변수를 찾아 순서대로 패턴을 따라간다. 그 url에 맞는 **view함수**를 호출하게된다.

### show\_urls

현재 프로젝트에 설정되어있는 URL을 한번에 볼 수 있다. 우선 `django-extensions` 패키지를 설치해준다. \[[설치하기](https://github.com/django-extensions/django-extensions)]

```bash
$ pip install django-extensions
$ pip list
Package             Version
------------------- -------
Django              2.1.7
django-extensions   2.1.6
djangorestframework 3.9.2
pip                 19.0.3
pytz                2018.9
setuptools          40.6.2
six                 1.12.0
```

그리고 난후 `settings.py`에 설정해준다.

```python
INSTALLED_APPS = (
    'django_extensions',
)
```

```bash
$ ./manage.py
[django_extensions]
    admin_generator
    clean_pyc
    clear_cache
    compile_pyc
    create_command
    create_jobs
    create_template_tags
    delete_squashed_migrations
    describe_form
    drop_test_database
    dumpscript
    export_emails
    find_template
    generate_password
    generate_secret_key
    graph_models
    mail_debug
    merge_model_instances
    notes
    passwd
    pipchecker
    print_settings
    print_user_for_session
    reset_db
    reset_schema
    runjob
    runjobs
    runprofileserver
    runscript
    runserver_plus
    set_default_site
    set_fake_emails
    set_fake_passwords
    shell_plus
    show_template_tags
    show_templatetags
    show_urls
    sqlcreate
    sqldiff
    sqldsn
    sync_s3
    syncdata
    unreferenced_files
    update_permissions
    validate_templates
```

여기서 url을 확인하려면 다음과 같이 명령어를 실행하면된다.

```bash
$ ./manage.py show_urls
/    rest_framework.routers.APIRootView    api-root
/\.<format>/    rest_framework.routers.APIRootView    api-root
/api-auth/login/    django.contrib.auth.views.LoginView    rest_framework:login
/api-auth/logout/    django.contrib.auth.views.LogoutView    rest_framework:logout
/groups/    quickstart.views.GroupViewSet    group-list
/groups/<pk>/    quickstart.views.GroupViewSet    group-detail
/groups/<pk>\.<format>/    quickstart.views.GroupViewSet    group-detail
/groups\.<format>/    quickstart.views.GroupViewSet    group-list
/users/    quickstart.views.UserViewSet    user-list
/users/<pk>/    quickstart.views.UserViewSet    user-detail
/users/<pk>\.<format>/    quickstart.views.UserViewSet    user-detail
/users\.<format>/    quickstart.views.UserViewSet    user-list
```

## View

각 View는 **1. 요청된 페이지의 내용이 담긴** [**HttpResponse 객체**](https://docs.djangoproject.com/ko/2.1/ref/request-response/#django.http.HttpResponse)**를 반환하거나, 2.** [**예외처리**](https://docs.djangoproject.com/ko/2.1/topics/http/views/#django.http.Http404)**(Http404)**&#xB97C; 하도록 되어있다.

1. 데이터 베이스 레코드 읽기
2. 템플릿 시스템 사용
3. PDF 생성
4. XML 출력
5. 실시간 ZIP 파일 생성

view는 다음과 같은 일을 할 수 있으며, python의 어떠한 라이브러리도 사용할 수 있다.

#### Database API 사용하기

```python
from django.http import HttpResponse
# 모델 import
from .models import Question

def index(request):
    last_question_list = Question.objects.order_by('-pub_date')[:5]
    output = ', '.join([q.question_text for q in last_question_list])
    return HttpResponse(output)
```

Database API에 접근하고 있지만 여기서는 문제가 있다. View에서 페이지의 디자인을 하드코딩 하고 있는 점이다. 템플릿(template)을 이용해서 python코드로 부터 디자인을 분리할 수 있다.

## 참조

* 공식문서 : <https://docs.djangoproject.com/ko/2.1/topics/http/urls/>
