---
title: "Menulis tampilan"
version: 5.1
locale: id
source: https://docs.djangoproject.com/id/5.1/topics/http/views/
canonical: https://djangodocs.dev/id/5.1/topics/http/views/
---
# Menulis tampilan

Fungsi tampilan, atau disingkat *view*, adalah fungsi Python yang mengambil permintaan web dan mengembalikan tanggapan web. Tanggapan ini dapat berupa isi HTML laman web, atau pengalihan, atau kesalahan 404, atau dokumen XML, atau gambar . . . atau apa pun, sungguh. Tampilan itu sendiri berisi logika sewenang-wenang apa pun yang diperlukan untuk mengembalikan respons itu. Kode ini dapat berada di mana saja yang Anda inginkan, asalkan berada di jalur Python anda. Tidak ada persyaratan lain - tidak ada "sihir", begitulah. Demi menempatkan kode *di suatu tempat*, konvensinya adalah meletakkan tampilan dalam berkas bernama `views.py`, yang ditempatkan di direktori proyek atau aplikasi anda.

## Tampilan sederhana

Disini adalah tampilan yang mengembalikan data dan waktu saat ini, sebagai sebuah dokumen HTML:

```
from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    html = '<html lang="en"><body>It is now %s.</body></html>' % now
    return HttpResponse(html)
```

Mari kita melangkah melalui kode ini satu baris pada saat bersamaan:

- Pertama, kami impor kelas [`HttpResponse`](/id/5.1/ref/request-response/#django.http.HttpResponse) dari modul [`django.http`](/id/5.1/ref/request-response/#module-django.http), bersama dengan pustaka `datetime` Python.
- Next, we define a function called `current_datetime`. This is the view
  function. Each view function takes an [`HttpRequest`](/id/5.1/ref/request-response/#django.http.HttpRequest)
  object as its first parameter, which is typically named `request`.

  Note that the name of the view function doesn't matter; it doesn't have to
  be named in a certain way in order for Django to recognize it. We're
  calling it `current_datetime` here, because that name clearly indicates
  what it does.
- Tampilan mengembalikan sebuah obyek [`HttpResponse`](/id/5.1/ref/request-response/#django.http.HttpResponse) yang mengandung tanggapan dibangkitkan. Setiap fungsi tampilan bertanggungjawab untuk mengembalikan sebuah obyek [`HttpResponse`](/id/5.1/ref/request-response/#django.http.HttpResponse). (ada pengecualian, tetapi kita akan kesana nanti.)

> **Zona Waktu Django**
>
> Django menyertakan sebuah pengaturan [`TIME_ZONE`](/id/5.1/ref/settings/#std-setting-TIME_ZONE) yang awalan pada `America/Chicago`. Ini mungkin bukan dimana anda tinggal, jadi anda mungkin ingin merubah itu dalam berkas pengaturan anda.

## Memetakan URL ke tampilan

Jadi, untuk mengikhtisarkan, fungsi tampilan ini mengembalikan sebuah halaman HTML yang menyertakan tanggal dan waktu saat ini. Untuk menampilkan tampilan ini pada URL tertentu, anda akan butuh membuat sebuah *URLconf*; lihat [Pengirim URL](/id/5.1/topics/http/urls/) untuk petunjuk.

## Mengembalikan kesalahan

Django provides help for returning HTTP error codes. There are subclasses of
[`HttpResponse`](/id/5.1/ref/request-response/#django.http.HttpResponse) for a number of common HTTP status codes
other than 200 (which means *"OK"*). You can find the full list of available
subclasses in the [request/response](/id/5.1/ref/request-response/#ref-httpresponse-subclasses)
documentation. Return an instance of one of those subclasses instead of a
normal [`HttpResponse`](/id/5.1/ref/request-response/#django.http.HttpResponse) in order to signify an error. For
example:

```
from django.http import HttpResponse, HttpResponseNotFound

def my_view(request):
    # ...
    if foo:
        return HttpResponseNotFound("<h1>Page not found</h1>")
    else:
        return HttpResponse("<h1>Page was found</h1>")
```

Tidak ada subkelas khusus untuk setiap kemungkinan kode tanggapan HTTP, sejak banyak dari mereka tidak akan menjadi yang umum. Bagaimanapun, seperti didokumentasikan dalam dokumentasi [`HttpResponse`](/id/5.1/ref/request-response/#django.http.HttpResponse), anda dapat juga melewatkan kode keadaan HTTP kedalam pembangun untuk [`HttpResponse`](/id/5.1/ref/request-response/#django.http.HttpResponse) untuk membuat kelas kembalian untuk kode keadaan apapun anda sukai. Sebagai contoh:

```
from django.http import HttpResponse

def my_view(request):
    # ...

    # Return a "created" (201) response code.
    return HttpResponse(status=201)
```

Karena kesalahan 404 sejauh ini paling umum kesalahan HTTP, ada sebuah cara paling mudah untuk menangani kesalahan-kesalahan tersebut.

### Pengecualian `Http404`

#### `class django.http.Http404`

Ketika anda mengembalikan sebuah kesalahan seperti [`HttpResponseNotFound`](/id/5.1/ref/request-response/#django.http.HttpResponseNotFound), anda bertanggung jawab untuk menentukan HTML dari menghasilkan halaman kesalahan:

```
return HttpResponseNotFound("<h1>Page not found</h1>")
```

Untuk kenyamanan, dan karena itu adalah ide bagus untuk memiliki halaman kesalahan 404 tetap terhadap situs anda, Django menyediakan sebuah pengecualian `Http404` pada titik apapun dalam fungsi tampilan, Django akan menangkap itu dan mengembalikan halaman kesalahan standar untuk aplikasi anda, bersama dengan sebuah kode kesalahan HTTP 404.

Contoh penggunaan:

```
from django.http import Http404
from django.shortcuts import render
from polls.models import Poll

def detail(request, poll_id):
    try:
        p = Poll.objects.get(pk=poll_id)
    except Poll.DoesNotExist:
        raise Http404("Poll does not exist")
    return render(request, "polls/detail.html", {"poll": p})
```

Untuk menampilkan HTML disesuaikan ketika Django mengembalikan sebuah 404, anda dapat membuat sebuah cetakan HTML bernama `404.html` dan menempatkan itu dalam tingkat atas dari pohon cetakan anda. Cetakan anda kemudian akan dilayani ketika [`DEBUG`](/id/5.1/ref/settings/#std-setting-DEBUG) disetel menjadi `False`.

Ketika [`DEBUG`](/id/5.1/ref/settings/#std-setting-DEBUG) adalah `True`, anda dapat menyediakan sebuah pesan pada `Http404` dan itu akan muncul dalam cetakan mencari kesalahan 404 standar. Gunakan pesan-pesan ini untuk tujuan mencari kesalahan; mereka umumnya tidak cocok untuk digunakan dalam produksi cetakan 404.

## Menyesuaikan tampilan kesalahan

The default error views in Django should suffice for most web applications,
but can easily be overridden if you need any custom behavior. Specify the
handlers as seen below in your URLconf (setting them anywhere else will have no
effect).

Tampilan [`page_not_found()`](/id/5.1/ref/views/#django.views.defaults.page_not_found) ditimpa oleh [`handler404`](/id/5.1/ref/urls/#django.conf.urls.handler404):

```
handler404 = "mysite.views.my_custom_page_not_found_view"
```

Tampilan [`server_error()`](/id/5.1/ref/views/#django.views.defaults.server_error) ditimpa oleh [`handler500`](/id/5.1/ref/urls/#django.conf.urls.handler500):

```
handler500 = "mysite.views.my_custom_error_view"
```

Tampilan [`permission_denied()`](/id/5.1/ref/views/#django.views.defaults.permission_denied) ditimpa oleh [`handler403`](/id/5.1/ref/urls/#django.conf.urls.handler403):

```
handler403 = "mysite.views.my_custom_permission_denied_view"
```

Tampilan [`bad_request()`](/id/5.1/ref/views/#django.views.defaults.bad_request) ditimpa oleh [`handler400`](/id/5.1/ref/urls/#django.conf.urls.handler400):

```
handler400 = "mysite.views.my_custom_bad_request_view"
```

> **See also**
>
> Gunakan pengaturan [`CSRF_FAILURE_VIEW`](/id/5.1/ref/settings/#std-setting-CSRF_FAILURE_VIEW) untuk menimpa tampilan kesalahan CSRF.

### Menguji penyesuaian tampilan kesalahan

Untuk menguji tanggapan dari penangan kesalahan penyesuaian, munculkan pengecualian yang sesuai dalam tampilan percobaan. Sebagai contoh:

```
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
from django.test import SimpleTestCase, override_settings
from django.urls import path

def response_error_handler(request, exception=None):
    return HttpResponse("Error handler content", status=403)

def permission_denied_view(request):
    raise PermissionDenied

urlpatterns = [
    path("403/", permission_denied_view),
]

handler403 = response_error_handler

# ROOT_URLCONF must specify the module that contains handler403 = ...
@override_settings(ROOT_URLCONF=__name__)
class CustomErrorHandlerTests(SimpleTestCase):
    def test_handler_renders_template_response(self):
        response = self.client.get("/403/")
        # Make assertions on the response here. For example:
        self.assertContains(response, "Error handler content", status_code=403)
```

## Tampilan asinkron

As well as being synchronous functions, views can also be asynchronous
("async") functions, normally defined using Python's `async def` syntax.
Django will automatically detect these and run them in an async context.
However, you will need to use an async server based on ASGI to get their
performance benefits.

Ini adalah contoh tampilan asinkronus:

```
import datetime
from django.http import HttpResponse

async def current_datetime(request):
    now = datetime.datetime.now()
    html = '<html lang="en"><body>It is now %s.</body></html>' % now
    return HttpResponse(html)
```

Anda dapat membaca lebih tengang dukungan asinkron Django, dan bagaimana cara terbaik menggunakan tampilan asinkron, di [Dukungan asinkronus](/id/5.1/topics/async/).
