# Dokumentasi Django 5.2.8

# Kerangka sistem pemeriksaan

Kerangka sistem pemeriksaan adalah kumpulan dari pemeriksaan tetap untuk memeriksa kebenaran proyek Django. Dia menemukan masalah umum dan menyediakan petunjuk untuk bagaimana memperbaiki mereka. Kerangka ini dapat diperpanjang sehingga anda dapat dengan mudah menambahkan pemeriksaan anda sendiri.

Pemeriksaan dapat dibangkitkan jelas melalui perintah `check`. Pemeriksaan dipicu tidak langsung sebelum kebanyakan perintah, termasuk `runserver` dan `migrate`. Untuk alasan penampilan, pemeriksaan tidak berjalan sebagai bagian dari tumpukan WSGI yang digunakan dalam pengembangan. Jika anda butuh menjalankan pemeriksaan sistem pada peladen pengembangan anda, picu mereka dengan jelas menggunakan `check`.

Kesalahan-kesalahan serius akan mencegah perintah Django (seperti `runserver`) dari menjalankan sama sekali. Masalah-masalah dilaporkan ke konsol. Jika anda telah memeriksa penyebab dari peringatan dan senang mengabaikan itu, anda dapat memyembunyikan peringatan khusus menggunakan pengaturan `SILENCED_SYSTEM_CHECKS` di berkas pengaturan proyek anda.

Sebuah daftar penuh dari semua pemeriksaan yang dapat dimunculkan oleh Django dapat ditemukan di System check reference.

## Menulis pemeriksaan anda sendiri

Kerangka kerja fleksibel dan mengizinkan anda menulis fungsi-fungsi yang melakukan jenis lain pemeriksaan anda mungkin butuhkan. Berikut adalah sebuah contoh potongan fungsi pemeriksaan:

    from django.core.checks import Error, register

    @register()
    def example_check(app_configs, **kwargs):
        errors = []
        # ... your check logic here
        if check_failed:
            errors.append(
                Error(
                    "an error",
                    hint="A hint.",
                    obj=checked_object,
                    id="myapp.E001",
                )
            )
        return errors

The check function must accept an `app_configs` argument; this argument is the list of applications that should be inspected. If `None`, the check must be run on all installed apps in the project.

The check will receive a `databases` keyword argument. This is a list of database aliases whose connections may be used to inspect database level configuration. If `databases` is `None`, the check must not use any database connections.

Argumen `**kwargs` diperlukan untuk perluasan di masa mendatang.

### Pesan

Fungsi harus mengembalikan sebuah daftar pesan. Jika tidak ada masalah ditemukan sebagai hasil dari pemeriksaan, fungsi pemeriksaaan harus mengembalikan sebuah daftar kosong.

Peringatan dan kesalahan dimunculkan oleh metode pemeriksaan harus berupa instance dari `CheckMessage`. Sebuah instance dari `CheckMessage` membungkus kesalahan tunggal dilaporkan atau peringatan. Itu juga menyediakan konteks dan petunjuk dapat diterapkan ke pesan, dan penciri unik yang digunakan untuk tujuan penyaringan.

Konsep sangat mirip ke pasan dari message framework atau the logging framework. Pesan-pesan dietiket dengan `level` menunjukkan kekerasan pesan.

Ada juga jalan pintas untuk membuat pesan dengan tingkatan umum lebih mudah. Ketika menggunakan kelas-kelas ini anda dapat menghilangkan argumen `level` karena itu disisipkan oleh nama kelas.

- `Debug`

- `Info`

- `Warning`

- `Error`

- `Critical`

### Mendaftarkan dan melabeli pemeriksaan

Akhirnya, fungsi pemeriksaan anda harus terdaftar jelas dengan sistem pemeriksaan regristrar. Pemeriksaan harus didaftarkan dalam sebuah berkas yang dimuat ketika aplikasi anda dimuat; sebagai contoh, di metode `AppConfig.ready()`.

register(*tags)(function)

Anda dapat melewatkan sebanyak etiket ke `register` seperti anda inginkan untuk melabelkan pemeriksaan anda. Pemeriksaan etiket sangat berguna sejak itu mengizinkan anda menjalankan hanya kelompok tertentu dari pemeriksaan. Sebagai contoh, untuk mendaftar pemeriksaan kesesuaian, anda akan membuat panggilan berikut:

    from django.core.checks import register, Tags

    @register(Tags.compatibility)
    def my_check(app_configs, **kwargs):
        # ... perform compatibility checks and collect errors
        return errors

Anda dapat mendaftar "deployment checks" yang hanya bersangkutan pada berkas pengaturan produksi seperti ini:

    @register(Tags.security, deploy=True)
    def my_check(app_configs, **kwargs): ...

Pemeriksaan ini hanya akan dijalankan jika pilihan `check --deploy` digunakan.

Anda dapat juga menggunakan `register` sebagai sebuah fungsi daripada sebuah penghias dengan melewatkan obyek callable (biasanya sebuah fungsi) sebagai argumen pertama pada `register`

Kode dibawah ini setara dengan kode diatas:

    def my_check(app_configs, **kwargs): ...

    register(my_check, Tags.security, deploy=True)

### Field, constraint, model, manager, template engine, task, and database checks

Dalam beberapa kasus, anda tidak butuh mendaftar fungsi pemeriksaan anda -- anda dapat mendukung pada pendaftaran yang ada.

Fields, constraints, models, model managers, template engines, task backends, and database backends all implement a `check()` method that is already registered with the check framework. If you want to add extra checks, you can extend the implementation on the base class, perform any extra checks you need, and append any messages to those generated by the base class. It's recommended that you delegate each check to separate methods.

Pertimbangkan sebuah contoh dimana anda sedang menerapkan bidang penyesuaian bernama `RangedIntegerField`. Bidang ini menambahkan argumen `min` dan `max` pada pembangun dari `IntegerField`. Anda mungkin ingin menambah sebuah pemeriksaan untuk memastikan bahwa pengguna menyediakan nilai minimal yang kurang atau setara pada nilai maksimal. Potongan kode berikut menunjukkan anda dapat menerapkan pemeriksaan ini:

    from django.core import checks
    from django.db import models

    class RangedIntegerField(models.IntegerField):
        def __init__(self, min=None, max=None, **kwargs):
            super().__init__(**kwargs)
            self.min = min
            self.max = max

        def check(self, **kwargs):
            # Call the superclass
            errors = super().check(**kwargs)

            # Do some custom checks and add messages to `errors`:
            errors.extend(self._check_min_max_values(**kwargs))

            # Return all errors and warnings
            return errors

        def _check_min_max_values(self, **kwargs):
            if self.min is not None and self.max is not None and self.min > self.max:
                return [
                    checks.Error(
                        "min greater than max.",
                        hint="Decrease min or increase max.",
                        obj=self,
                        id="myapp.E001",
                    )
                ]
            # When no error, return an empty list
            return []

Jika anda ingin menambah pemeriksaan pada pengelola model, anda akan mengambil pendekatan sama pada subkelas anda dari `Manager`.

Jika anda ingin menambah sebuah pemeriksaan pada kelas model, pendekatan adalah hampir sama: perbedaan hanya bahwa pemeriksaan adalah metode kelas, bukan metode instance:

    class MyModel(models.Model):
        @classmethod
        def check(cls, **kwargs):
            errors = super().check(**kwargs)
            # ... your own checks ...
            return errors

Changed in Django 6.0:

In older versions, constraints didn't implement a `check()` method.

### Menulis percobaan

Pesan dapat dibandingkan. Itu mengizinakan anda dengan mudah menulis percobaan:

    from django.core.checks import Error

    errors = checked_object.check()
    expected_errors = [
        Error(
            "an error",
            hint="A hint.",
            obj=checked_object,
            id="myapp.E001",
        )
    ]
    self.assertEqual(errors, expected_errors)

#### Writing integration tests

Given the need to register certain checks when the application loads, it can be useful to test their integration within the system checks framework. This can be accomplished by using the `call_command()` function.

For example, this test demonstrates that the `SITE_ID` setting must be an integer, a built-in check from the sites framework:

    from django.core.management import call_command
    from django.core.management.base import SystemCheckError
    from django.test import SimpleTestCase, modify_settings, override_settings

    class SystemCheckIntegrationTest(SimpleTestCase):
        @override_settings(SITE_ID="non_integer")
        @modify_settings(INSTALLED_APPS={"prepend": "django.contrib.sites"})
        def test_non_integer_site_id(self):
            message = "(sites.E101) The SITE_ID setting must be an integer."
            with self.assertRaisesMessage(SystemCheckError, message):
                call_command("check")

Consider the following check which issues a warning on deployment if a custom setting named `ENABLE_ANALYTICS` is not set to `True`:

    from django.conf import settings
    from django.core.checks import Warning, register

    @register("myapp", deploy=True)
    def check_enable_analytics_is_true_on_deploy(app_configs, **kwargs):
        errors = []
        if getattr(settings, "ENABLE_ANALYTICS", None) is not True:
            errors.append(
                Warning(
                    "The ENABLE_ANALYTICS setting should be set to True in deployment.",
                    id="myapp.W001",
                )
            )
        return errors

Given that this check will not raise a `SystemCheckError`, the presence of the warning message in the `stderr` output can be asserted like so:

    from io import StringIO

    from django.core.management import call_command
    from django.test import SimpleTestCase, override_settings

    class EnableAnalyticsDeploymentCheckTest(SimpleTestCase):
        @override_settings(ENABLE_ANALYTICS=None)
        def test_when_set_to_none(self):
            stderr = StringIO()
            call_command("check", "-t", "myapp", "--deploy", stderr=stderr)
            message = (
                "(myapp.W001) The ENABLE_ANALYTICS setting should be set "
                "to True in deployment."
            )
            self.assertIn(message, stderr.getvalue())