{"title":"Penyesuaian Pencarian","version":"1.9","locale":"id","docname":"howto/custom-lookups","url":"/id/1.9/howto/custom-lookups/","canonical":"https://djangodocs.dev/id/1.9/howto/custom-lookups/","summary":"Django menawarkan beragam luas dari built-in lookups untuk penyaringan (sebagai contoh, exact dan icontains ). Dokumentasi ini menjelaskan bagaimana menulis…","html":"<h1>Penyesuaian Pencarian<a class=\"heading-anchor\" href=\"#custom-lookups\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Django menawarkan beragam luas dari <a class=\"reference internal\" href=\"/id/1.9/ref/models/querysets/#field-lookups\"><span class=\"std std-ref\">built-in lookups</span></a> untuk penyaringan (sebagai contoh, <code class=\"docutils literal notranslate\"><span class=\"pre\">exact</span></code> dan <code class=\"docutils literal notranslate\"><span class=\"pre\">icontains</span></code>). Dokumentasi ini menjelaskan bagaimana menulis penyesuaian pencarian dan bagaimana mengubah pekerjaan dari pencarian yang ada. Untuk acuan API dari pencarian, lihat <a class=\"reference internal\" href=\"/id/1.9/ref/models/lookups/\"><span class=\"doc\">Lookup API reference</span></a>.</p>\n<section id=\"a-simple-lookup-example\">\n<h2>Sebuah contoh pencarian sederhana<a class=\"heading-anchor\" href=\"#a-simple-lookup-example\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Mari kita mulai dengan sebuah penyesuaian pencarian sederhana. Kami akan menulis penyesuaian pencarian <code class=\"docutils literal notranslate\"><span class=\"pre\">ne</span></code> yang bekerja berlawawan ke <code class=\"docutils literal notranslate\"><span class=\"pre\">exact</span></code>. <code class=\"docutils literal notranslate\"><span class=\"pre\">Author.objects.filter(name__ne='Jack')</span></code> akan dirubah ke SQL:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"s2\">&quot;author&quot;</span><span class=\"o\">.</span><span class=\"s2\">&quot;name&quot;</span> <span class=\"o\">&lt;&gt;</span> <span class=\"s1\">&#39;Jack&#39;</span>\n</code></pre></div>\n<p>Backend SQL berdisi sendiri, sehingga kita tidak perlu khawatir tentang basisdata berbeda.</p>\n<p>Terdapat dua langkah untuk membuat ini bekerja. Pertama kami butuh menerapkan pencarian, kemudian kami butuh mengatakan Django tentang ini. Penerapannya sangat mudah:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Lookup</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">NotEqual</span><span class=\"p\">(</span><span class=\"n\">Lookup</span><span class=\"p\">):</span>\n    <span class=\"n\">lookup_name</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;ne&#39;</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">as_sql</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">):</span>\n        <span class=\"n\">lhs</span><span class=\"p\">,</span> <span class=\"n\">lhs_params</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">process_lhs</span><span class=\"p\">(</span><span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">)</span>\n        <span class=\"n\">rhs</span><span class=\"p\">,</span> <span class=\"n\">rhs_params</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">process_rhs</span><span class=\"p\">(</span><span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">)</span>\n        <span class=\"n\">params</span> <span class=\"o\">=</span> <span class=\"n\">lhs_params</span> <span class=\"o\">+</span> <span class=\"n\">rhs_params</span>\n        <span class=\"k\">return</span> <span class=\"s1\">&#39;</span><span class=\"si\">%s</span><span class=\"s1\"> &lt;&gt; </span><span class=\"si\">%s</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">lhs</span><span class=\"p\">,</span> <span class=\"n\">rhs</span><span class=\"p\">),</span> <span class=\"n\">params</span>\n</code></pre></div>\n<p>Untuk mendaftar pencarian <code class=\"docutils literal notranslate\"><span class=\"pre\">NotEqual</span></code> kami akan butuh memanggil <code class=\"docutils literal notranslate\"><span class=\"pre\">register_lookup</span></code> pada kelas bidang kami ingin pencarian menjadi tersedia. Dalam kasus ini, pencarian dapat dimengerti pada semua subkelas <code class=\"docutils literal notranslate\"><span class=\"pre\">Field</span></code>, jadi kami mendaftarkannya dengan <code class=\"docutils literal notranslate\"><span class=\"pre\">Field</span></code> secara langsung:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models.fields</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Field</span>\n<span class=\"n\">Field</span><span class=\"o\">.</span><span class=\"n\">register_lookup</span><span class=\"p\">(</span><span class=\"n\">NotEqual</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Pendaftaran pencarian dapat juga dikerjakan menggunakan corak decorator:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models.fields</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Field</span>\n\n<span class=\"nd\">@Field</span><span class=\"o\">.</span><span class=\"n\">register_lookup</span>\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">NotEqualLookup</span><span class=\"p\">(</span><span class=\"n\">Lookup</span><span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n</code></pre></div>\n<aside class=\"version-note version-changed\" data-version=\"1.8\">\n<p class=\"version-note-title\">Changed in Django 1.8</p><p>Kemampuan untuk menggunakan coran decorator telah ditambahkan.</p>\n</aside>\n<p>Kami sekarang dapat menggunakan <code class=\"docutils literal notranslate\"><span class=\"pre\">foo__ne</span></code> untuk setiap bidang <code class=\"docutils literal notranslate\"><span class=\"pre\">foo</span></code>. Anda akan butuh memastikan bahwa pendaftaran ini terjadi sebelum anda mencoba membuat kumpulan permintaan menggunakannya. Anda dapat menempatkan penerapan dalam sebuah berkas <code class=\"docutils literal notranslate\"><span class=\"pre\">models.py</span></code>, atau mendaftarkan pencarian dalam cara <code class=\"docutils literal notranslate\"><span class=\"pre\">ready()</span></code> dari sebuah <code class=\"docutils literal notranslate\"><span class=\"pre\">AppConfig</span></code>.</p>\n<p>Melihat lebih dekat pada penerapan, atribut dibutuhkan pertama adalah <code class=\"docutils literal notranslate\"><span class=\"pre\">lookup_name</span></code>. Ini mengizinkan ORM untuk memahami bagaimana mengartikan <code class=\"docutils literal notranslate\"><span class=\"pre\">name__ne</span></code> dan menggunakan <code class=\"docutils literal notranslate\"><span class=\"pre\">NotEqual</span></code> utnuk membangkitkan SQL. Berdasarkan pemufakatan, nama-nama ini selalu deretan karakter huruf kecil mengandung hanya huruf, tetapi persyaratan mutlak adalah bahwa itu harus mengandung deretan karakter <code class=\"docutils literal notranslate\"><span class=\"pre\">__</span></code>.</p>\n<p>We then need to define the <code class=\"docutils literal notranslate\"><span class=\"pre\">as_sql</span></code> method. This takes a <code class=\"docutils literal notranslate\"><span class=\"pre\">SQLCompiler</span></code>\nobject, called <code class=\"docutils literal notranslate\"><span class=\"pre\">compiler</span></code>,  and the active database connection.\n<code class=\"docutils literal notranslate\"><span class=\"pre\">SQLCompiler</span></code> objects are not documented, but the only thing we need to know\nabout them is that they have a <code class=\"docutils literal notranslate\"><span class=\"pre\">compile()</span></code> method which returns a tuple\ncontaining an SQL string, and the parameters to be interpolated into that\nstring. In most cases, you don't need to use it directly and can pass it on to\n<code class=\"docutils literal notranslate\"><span class=\"pre\">process_lhs()</span></code> and <code class=\"docutils literal notranslate\"><span class=\"pre\">process_rhs()</span></code>.</p>\n<p>Sebuah <code class=\"docutils literal notranslate\"><span class=\"pre\">Lookup</span></code> bekerja terhadap dua nilai, <code class=\"docutils literal notranslate\"><span class=\"pre\">lhs</span></code> dan <code class=\"docutils literal notranslate\"><span class=\"pre\">rhs</span></code>, kepanjangan dari left-hand side dan right-hand side. Left-hand side biasanya acuan bidang, tetapi dia dapat menjadi apapun menerapkan <a class=\"reference internal\" href=\"/id/1.9/ref/models/lookups/#query-expression\"><span class=\"std std-ref\">query expression API</span></a>. Right-hand adalah nilai diberikan oleh pengguna. Dalam contoh <code class=\"docutils literal notranslate\"><span class=\"pre\">Author.objects.filter(name__ne='Jack')</span></code>, the left-hand side adalah sebauh acuan pada bidang <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> dari model <code class=\"docutils literal notranslate\"><span class=\"pre\">Author</span></code>, dan <code class=\"docutils literal notranslate\"><span class=\"pre\">'Jack'</span></code> adalah the right-hand side.</p>\n<p>Kami memanggil <code class=\"docutils literal notranslate\"><span class=\"pre\">process_lhs</span></code> dan <code class=\"docutils literal notranslate\"><span class=\"pre\">process_rhs</span></code> untuk merubah mereka kedalam nilai-nilai kami butuh untuk SQL menggunakan obyek <code class=\"docutils literal notranslate\"><span class=\"pre\">compiler</span></code> digambarkan sebelumnya. Cara ini mengembalikan tuple mengandung beberapa SQL dan parameter untuk ditambahkan kedaam SQL itu, seperti yang kita perlu untuk mengembalikan cara <code class=\"docutils literal notranslate\"><span class=\"pre\">as_sql</span></code> kami. Dalam contoh diatas, <code class=\"docutils literal notranslate\"><span class=\"pre\">process_lhs</span></code> mengembalikan <code class=\"docutils literal notranslate\"><span class=\"pre\">('&quot;author&quot;.&quot;name&quot;',</span> <span class=\"pre\">[])</span></code> dan <code class=\"docutils literal notranslate\"><span class=\"pre\">process_rhs</span></code> mengembalikan <code class=\"docutils literal notranslate\"><span class=\"pre\">('&quot;%s&quot;',</span> <span class=\"pre\">['Jack'])</span></code>. Dalam contoh ini tidak ada parameter untuk left hand side, tetapi ini akan tergantung pada obyek kita punya, jadi jami masih butuh menyertakan merekan dalam parameter kami kembalikan.</p>\n<p>Finally we combine the parts into an SQL expression with <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;&gt;</span></code>, and supply all\nthe parameters for the query. We then return a tuple containing the generated\nSQL string and the parameters.</p>\n</section>\n<section id=\"a-simple-transformer-example\">\n<h2>Contoh perubahan sederhana<a class=\"heading-anchor\" href=\"#a-simple-transformer-example\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Penyesuaian pencarian diatas adalah hebat, tetapi dalam beberapa kasus anda mungkin ingin dapat merangkai pencarian bersama-sama. Sebagai contoh, mari kita misalnya kami sedang membangun sebuah aplikasi dimana kami ingin membuat penggunaan dari operator <code class=\"docutils literal notranslate\"><span class=\"pre\">abs()</span></code>. Kami mempunyai sebuah model <code class=\"docutils literal notranslate\"><span class=\"pre\">Experiment</span></code> yang merekam sebuah nilai awal, nilai akhir, dan perubahan (awal - akhir). Kami akan suka menemukan semua percobaan dimana perubahan setara pada bilangan tertentu (<code class=\"docutils literal notranslate\"><span class=\"pre\">Experiment.objects.filter(change__abs=27)</span></code>), atau dimana itu tidak melebihi bilangan tertentu (<code class=\"docutils literal notranslate\"><span class=\"pre\">Experiment.objects.filter(change__abs__lt=27)</span></code>).</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Catatan</p>\n<p>Contoh ini agak dibikin, tetapi dia menunjukkan jangkauan fungsionalitas yang memungkinkan dalam cara backend basisdata berdisi sendiri, tanpa menggandakan fungsionalitas yang sudah ada di Django.</p>\n</aside>\n<p>Kami akan mulai dengan menulis sebuah pengubah <code class=\"docutils literal notranslate\"><span class=\"pre\">AbsoluteValue</span></code>. Ini akan menggunakan fungsi SQL <code class=\"docutils literal notranslate\"><span class=\"pre\">ABS()</span></code> untuk merubah nilai sebelum dibandingkan:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Transform</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">AbsoluteValue</span><span class=\"p\">(</span><span class=\"n\">Transform</span><span class=\"p\">):</span>\n    <span class=\"n\">lookup_name</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;abs&#39;</span>\n    <span class=\"n\">function</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;ABS&#39;</span>\n</code></pre></div>\n<p>Selanjutnya, mari kita daftarkan sebagai <code class=\"docutils literal notranslate\"><span class=\"pre\">IntegerField</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">IntegerField</span>\n<span class=\"n\">IntegerField</span><span class=\"o\">.</span><span class=\"n\">register_lookup</span><span class=\"p\">(</span><span class=\"n\">AbsoluteValue</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Kami dapat sekarang menjalankan permintaan kami punyai sebelumnya. <code class=\"docutils literal notranslate\"><span class=\"pre\">Experiment.objects.filter(change__abs=27)</span></code> akan membangkitkan SQL berikut:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">SELECT</span> <span class=\"o\">...</span> <span class=\"n\">WHERE</span> <span class=\"n\">ABS</span><span class=\"p\">(</span><span class=\"s2\">&quot;experiments&quot;</span><span class=\"o\">.</span><span class=\"s2\">&quot;change&quot;</span><span class=\"p\">)</span> <span class=\"o\">=</span> <span class=\"mi\">27</span>\n</code></pre></div>\n<p>Dengan menggunakan <code class=\"docutils literal notranslate\"><span class=\"pre\">Transform</span></code> dari pada <code class=\"docutils literal notranslate\"><span class=\"pre\">Lookup</span></code> itu berarti kami dapat merangkai pencarian lebih lanjut setelahnya. Jadi <code class=\"docutils literal notranslate\"><span class=\"pre\">Experiment.objects.filter(change__abs__lt=27)</span></code> akan membangkitkan SQL berikut:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">SELECT</span> <span class=\"o\">...</span> <span class=\"n\">WHERE</span> <span class=\"n\">ABS</span><span class=\"p\">(</span><span class=\"s2\">&quot;experiments&quot;</span><span class=\"o\">.</span><span class=\"s2\">&quot;change&quot;</span><span class=\"p\">)</span> <span class=\"o\">&lt;</span> <span class=\"mi\">27</span>\n</code></pre></div>\n<p>Catat bahwa dalam kasus terdapat tidak ada pencarian lain yang ditentukan, Django menterjemahkan <code class=\"docutils literal notranslate\"><span class=\"pre\">change__abs=27</span></code> sebagai <code class=\"docutils literal notranslate\"><span class=\"pre\">change__abs__exact=27</span></code>.</p>\n<p>Ketika mencari pencarian mana yang diizinkan setelah <code class=\"docutils literal notranslate\"><span class=\"pre\">Transform</span></code> diberlakukan, Django menggunakan atribut <code class=\"docutils literal notranslate\"><span class=\"pre\">output_field</span></code>. Kami tidak butuh menentukan ini disini jika itu tidak berubah, tetapi seharusnya kami memberlakukan <code class=\"docutils literal notranslate\"><span class=\"pre\">AbsoluteValue</span></code> pada beberapa bidang yang mewakili jenis lebih rumit (sebagai contoh sebuah titik relatif ke yang asli, atau angka rumit) kemudian kami mungkin ingin menentukan bahwa perubahan mengembalikan jenis <code class=\"docutils literal notranslate\"><span class=\"pre\">FloatField</span></code> untuk pencarian lebih lanjut. Ini dapat dikerjakan dengan menambahkan sebuah atribut <code class=\"docutils literal notranslate\"><span class=\"pre\">output_field</span></code> untuk perubahan:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">FloatField</span><span class=\"p\">,</span> <span class=\"n\">Transform</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">AbsoluteValue</span><span class=\"p\">(</span><span class=\"n\">Transform</span><span class=\"p\">):</span>\n    <span class=\"n\">lookup_name</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;abs&#39;</span>\n    <span class=\"n\">function</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;ABS&#39;</span>\n\n    <span class=\"nd\">@property</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">output_field</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"n\">FloatField</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Ini memastikan bahwa pencarian lebih lanjut seperti <code class=\"docutils literal notranslate\"><span class=\"pre\">abs__lte</span></code> berperilaku seperti mereka lakukan untuk <code class=\"docutils literal notranslate\"><span class=\"pre\">FloatField</span></code>.</p>\n</section>\n<section id=\"writing-an-efficient-abs-lt-lookup\">\n<h2>Menulis sebuah pencarian <code class=\"docutils literal notranslate\"><span class=\"pre\">abs__lt</span></code> efisien<a class=\"heading-anchor\" href=\"#writing-an-efficient-abs-lt-lookup\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Ketika menggunakan penulisan diatas pencarian <code class=\"docutils literal notranslate\"><span class=\"pre\">abs</span></code>, keluaran SQL tidak menggunakan indeks secara efisien dalam beberapa kasus. Khususnya, ketika kami menggunakan <code class=\"docutils literal notranslate\"><span class=\"pre\">change__abs__lt=27</span></code>, ini setara pada <code class=\"docutils literal notranslate\"><span class=\"pre\">change__gt=-27</span></code> AND <code class=\"docutils literal notranslate\"><span class=\"pre\">change__lt=27</span></code>. (Untuk kasus <code class=\"docutils literal notranslate\"><span class=\"pre\">lte</span></code> kami akan menggunakan SQL <code class=\"docutils literal notranslate\"><span class=\"pre\">BETWEEN</span></code>).</p>\n<p>Jadi kami akan <code class=\"docutils literal notranslate\"><span class=\"pre\">Experiment.objects.filter(change__abs__lt=27)</span></code> untuk membangkitkan SQL berikut:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">SELECT</span> <span class=\"o\">..</span> <span class=\"n\">WHERE</span> <span class=\"s2\">&quot;experiments&quot;</span><span class=\"o\">.</span><span class=\"s2\">&quot;change&quot;</span> <span class=\"o\">&lt;</span> <span class=\"mi\">27</span> <span class=\"n\">AND</span> <span class=\"s2\">&quot;experiments&quot;</span><span class=\"o\">.</span><span class=\"s2\">&quot;change&quot;</span> <span class=\"o\">&gt;</span> <span class=\"o\">-</span><span class=\"mi\">27</span>\n</code></pre></div>\n<p>Peneprapannya adalah:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Lookup</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">AbsoluteValueLessThan</span><span class=\"p\">(</span><span class=\"n\">Lookup</span><span class=\"p\">):</span>\n    <span class=\"n\">lookup_name</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;lt&#39;</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">as_sql</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">):</span>\n        <span class=\"n\">lhs</span><span class=\"p\">,</span> <span class=\"n\">lhs_params</span> <span class=\"o\">=</span> <span class=\"n\">compiler</span><span class=\"o\">.</span><span class=\"n\">compile</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">lhs</span><span class=\"o\">.</span><span class=\"n\">lhs</span><span class=\"p\">)</span>\n        <span class=\"n\">rhs</span><span class=\"p\">,</span> <span class=\"n\">rhs_params</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">process_rhs</span><span class=\"p\">(</span><span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">)</span>\n        <span class=\"n\">params</span> <span class=\"o\">=</span> <span class=\"n\">lhs_params</span> <span class=\"o\">+</span> <span class=\"n\">rhs_params</span> <span class=\"o\">+</span> <span class=\"n\">lhs_params</span> <span class=\"o\">+</span> <span class=\"n\">rhs_params</span>\n        <span class=\"k\">return</span> <span class=\"s1\">&#39;</span><span class=\"si\">%s</span><span class=\"s1\"> &lt; </span><span class=\"si\">%s</span><span class=\"s1\"> AND </span><span class=\"si\">%s</span><span class=\"s1\"> &gt; -</span><span class=\"si\">%s</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">lhs</span><span class=\"p\">,</span> <span class=\"n\">rhs</span><span class=\"p\">,</span> <span class=\"n\">lhs</span><span class=\"p\">,</span> <span class=\"n\">rhs</span><span class=\"p\">),</span> <span class=\"n\">params</span>\n\n<span class=\"n\">AbsoluteValue</span><span class=\"o\">.</span><span class=\"n\">register_lookup</span><span class=\"p\">(</span><span class=\"n\">AbsoluteValueLessThan</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Terdapat sepasang hal penting sedang terjadi. Pertama, <code class=\"docutils literal notranslate\"><span class=\"pre\">AbsoluteValueLessThan</span></code> tidak memanggil <code class=\"docutils literal notranslate\"><span class=\"pre\">process_lhs()</span></code>. Malahan dia melewati perubahan dari <code class=\"docutils literal notranslate\"><span class=\"pre\">lhs</span></code> dikerjakan oleh <code class=\"docutils literal notranslate\"><span class=\"pre\">AbsoluteValue</span></code> dan menggunakan <code class=\"docutils literal notranslate\"><span class=\"pre\">lhs</span></code> asli. Yaitu, kami ingin mendapatkan <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;experiments&quot;.&quot;change&quot;</span></code> bukan <code class=\"docutils literal notranslate\"><span class=\"pre\">ABS(&quot;experiments&quot;.&quot;change&quot;)</span></code>. Mengacu secara langsung pada <code class=\"docutils literal notranslate\"><span class=\"pre\">self.lhs.lhs</span></code> adalah aman <code class=\"docutils literal notranslate\"><span class=\"pre\">AbsoluteValueLessThan</span></code> dapat diakses hanya dari pencarian <code class=\"docutils literal notranslate\"><span class=\"pre\">AbsoluteValue</span></code>, yaitu <code class=\"docutils literal notranslate\"><span class=\"pre\">lhs</span></code> selalu sebuah instance dari <code class=\"docutils literal notranslate\"><span class=\"pre\">AbsoluteValue</span></code>.</p>\n<p>Perhaikan juga bahwa kedua sisi menggunakan banyak waktu dalam permintaan parameter butuh untuk dikandung <code class=\"docutils literal notranslate\"><span class=\"pre\">lhs_params</span></code> dan <code class=\"docutils literal notranslate\"><span class=\"pre\">rhs_params</span></code> banyak waktu.</p>\n<p>Permintaan akhir melakukan pembalikan (<code class=\"docutils literal notranslate\"><span class=\"pre\">27</span></code> ke <code class=\"docutils literal notranslate\"><span class=\"pre\">-27</span></code>) secara langsung di basisdata. Alasan untuk melakukan ini adalah bahwa jika <code class=\"docutils literal notranslate\"><span class=\"pre\">self.rhs</span></code> sesuatu lain daripada nilai integer polos (sebagai contoh sebuah acuan <code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code>) kami tidak dapat melakukan perubahan dalam Python.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Catatan</p>\n<p>Faktanya, kebanyakan pencarian dengan <code class=\"docutils literal notranslate\"><span class=\"pre\">__abs</span></code> dapat diterapkan sebagai jangkauan permintaan seperti ini, dan pada kebanyakan backend basisdata sepertinya lebih bijaksana untuk dilakukan sehingga anda dapat membuat penggunaan indeks. Bagaimanapun dengan PostgreSQL anda mungkin ingin menambahkan indeks pada <code class=\"docutils literal notranslate\"><span class=\"pre\">abs(change)</span></code> yang akan mengizinkan permintaan ini menjadi lebih efisien.</p>\n</aside>\n</section>\n<section id=\"a-bilateral-transformer-example\">\n<h2>Sebuah contoh perubahan timbal balik<a class=\"heading-anchor\" href=\"#a-bilateral-transformer-example\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Contoh <code class=\"docutils literal notranslate\"><span class=\"pre\">AbsoluteValue</span></code> kami obrolkan sebelumnya adalah sebuah perubahan yang berlaku pada left-hand side dari pencarian. Mungkin disana beberapa kasus dimana anda ingin perubahan diberlakukan pada kedua left-hand side and the right-hand side. Sebagai contoh, jika anda ingin menyaring kumpulan permintaan berdasarkan pada persamaan left and right-hand side kebal pada beberapa fungsi SQL.</p>\n<p>Mari kita ujikan contoh sederhana dari perubahan kasus tidak peka disini. Perubahan ini tidak sangat berguna dalam praktiknya ketika Django sudah datang dengan seikat pencarian siap pakai tidak peka, tetapi dia akan menjadi pertunjukan bagus dari perubahan timbal balik dalam sebuah cara basisdata-agnostik.</p>\n<p>Kami menentukan sebuab perubahan UpperCase` yang menggunakan fungsi SQL <code class=\"docutils literal notranslate\"><span class=\"pre\">UPPER()</span></code> untuk merubah nilai sebelum dibandingkan. Kami menentukan <a class=\"reference internal\" href=\"/id/1.9/ref/models/lookups/#django.db.models.Transform.bilateral\" title=\"django.db.models.Transform.bilateral\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">bilateral</span> <span class=\"pre\">=</span> <span class=\"pre\">True</span></code></a> untuk mengindikasikan bahwa perubahan ini harus berlaku pada kedua <code class=\"docutils literal notranslate\"><span class=\"pre\">lhs</span></code> and <code class=\"docutils literal notranslate\"><span class=\"pre\">rhs</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Transform</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">UpperCase</span><span class=\"p\">(</span><span class=\"n\">Transform</span><span class=\"p\">):</span>\n    <span class=\"n\">lookup_name</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;upper&#39;</span>\n    <span class=\"n\">function</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;UPPER&#39;</span>\n    <span class=\"n\">bilateral</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n</code></pre></div>\n<p>Selanjutnya, mari kita mendaftarkannya:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">CharField</span><span class=\"p\">,</span> <span class=\"n\">TextField</span>\n<span class=\"n\">CharField</span><span class=\"o\">.</span><span class=\"n\">register_lookup</span><span class=\"p\">(</span><span class=\"n\">UpperCase</span><span class=\"p\">)</span>\n<span class=\"n\">TextField</span><span class=\"o\">.</span><span class=\"n\">register_lookup</span><span class=\"p\">(</span><span class=\"n\">UpperCase</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Sekarang, kumpulan permintaan <code class=\"docutils literal notranslate\"><span class=\"pre\">Author.objects.filter(name__upper=&quot;doe&quot;)</span></code> akan membangkitkan sebuah permintaan kasus tidak peka seperti ini:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">SELECT</span> <span class=\"o\">...</span> <span class=\"n\">WHERE</span> <span class=\"n\">UPPER</span><span class=\"p\">(</span><span class=\"s2\">&quot;author&quot;</span><span class=\"o\">.</span><span class=\"s2\">&quot;name&quot;</span><span class=\"p\">)</span> <span class=\"o\">=</span> <span class=\"n\">UPPER</span><span class=\"p\">(</span><span class=\"s1\">&#39;doe&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"writing-alternative-implementations-for-existing-lookups\">\n<h2>Menulis penerapan cara lain untuk pencarian yang ada<a class=\"heading-anchor\" href=\"#writing-alternative-implementations-for-existing-lookups\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Terkadang penjaja basisdata berbeda membutuhkan SQL berbeda untuk pekerjaan yang sama. Untuk contoh ini kami akan menulis kembali sebuah penyesuaian penerapan untuk MySQL untuk penghubung NotEqual. Dari pada <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;&gt;</span></code> kami akan menggunakan penghubung <code class=\"docutils literal notranslate\"><span class=\"pre\">!=</span></code>. (Catat bahwa dalam kenyataan hampir semua basisdata mendukung keduanya, termasuk semua basisdata resmi didukung oleh Django).</p>\n<p>Kami dapat merubah kebiasaan pada backend spesifik dengan membuat subkelas dari <code class=\"docutils literal notranslate\"><span class=\"pre\">NotEqual</span></code> dengan sebuah cara <code class=\"docutils literal notranslate\"><span class=\"pre\">as_mysql</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MySQLNotEqual</span><span class=\"p\">(</span><span class=\"n\">NotEqual</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">as_mysql</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">):</span>\n        <span class=\"n\">lhs</span><span class=\"p\">,</span> <span class=\"n\">lhs_params</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">process_lhs</span><span class=\"p\">(</span><span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">)</span>\n        <span class=\"n\">rhs</span><span class=\"p\">,</span> <span class=\"n\">rhs_params</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">process_rhs</span><span class=\"p\">(</span><span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">)</span>\n        <span class=\"n\">params</span> <span class=\"o\">=</span> <span class=\"n\">lhs_params</span> <span class=\"o\">+</span> <span class=\"n\">rhs_params</span>\n        <span class=\"k\">return</span> <span class=\"s1\">&#39;</span><span class=\"si\">%s</span><span class=\"s1\"> != </span><span class=\"si\">%s</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">lhs</span><span class=\"p\">,</span> <span class=\"n\">rhs</span><span class=\"p\">),</span> <span class=\"n\">params</span>\n\n<span class=\"n\">Field</span><span class=\"o\">.</span><span class=\"n\">register_lookup</span><span class=\"p\">(</span><span class=\"n\">MySQLNotEqual</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Kami dapat mendaftarkannya dengan <code class=\"docutils literal notranslate\"><span class=\"pre\">Field</span></code>. Dia memakan tempat dari kelas <code class=\"docutils literal notranslate\"><span class=\"pre\">NotEqual</span></code> asli seperti dia mempunyai <code class=\"docutils literal notranslate\"><span class=\"pre\">lookup_name</span></code> sama.</p>\n<p>Ketika menyusun sebuah permintaan, Django pertama mencari cara <code class=\"docutils literal notranslate\"><span class=\"pre\">as_%s</span> <span class=\"pre\">%</span> <span class=\"pre\">connection.vendor</span></code>, dan kemudian kembali ke <code class=\"docutils literal notranslate\"><span class=\"pre\">as_sql</span></code>. Nama penjaja untuk membangun backend adalah <code class=\"docutils literal notranslate\"><span class=\"pre\">sqlite</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">postgresql</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">oracle</span></code> dan <code class=\"docutils literal notranslate\"><span class=\"pre\">mysql</span></code>.</p>\n</section>\n<section id=\"how-django-determines-the-lookups-and-transforms-which-are-used\">\n<h2>Bagaimana Django menentuka pencarian dan merubah yang sedang digunakan<a class=\"heading-anchor\" href=\"#how-django-determines-the-lookups-and-transforms-which-are-used\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Dalam beberapa kasus anda mungkin berharap untuk secara dinamis merubah <code class=\"docutils literal notranslate\"><span class=\"pre\">Transform</span></code> atau <code class=\"docutils literal notranslate\"><span class=\"pre\">Lookup</span></code> dikembalikan berdasarkan pada nama dilewatkan, daripada memperbaikinya. Sebagai sebuah contoh, anda dapat mempunyai sebuah bidang yang menyimpan kordinat atau dimensi berubah-ubah dan berharap untuk mengizinkan sebuah sintaksis seperti <code class=\"docutils literal notranslate\"><span class=\"pre\">.filter(coords__x7=4)</span></code> untuk mengembalikan obyek dimana kordinat 7 mempunyai nilai 4. Untuk melakukan ini, anda akan mengesampingkan <code class=\"docutils literal notranslate\"><span class=\"pre\">get_lookup</span></code> dengan sesuatu seperti:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CoordinatesField</span><span class=\"p\">(</span><span class=\"n\">Field</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_lookup</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">lookup_name</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"n\">lookup_name</span><span class=\"o\">.</span><span class=\"n\">startswith</span><span class=\"p\">(</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">):</span>\n            <span class=\"k\">try</span><span class=\"p\">:</span>\n                <span class=\"n\">dimension</span> <span class=\"o\">=</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">lookup_name</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:])</span>\n            <span class=\"k\">except</span> <span class=\"ne\">ValueError</span><span class=\"p\">:</span>\n                <span class=\"k\">pass</span>\n            <span class=\"k\">else</span><span class=\"p\">:</span>\n                <span class=\"k\">return</span> <span class=\"n\">get_coordinate_lookup</span><span class=\"p\">(</span><span class=\"n\">dimension</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">CoordinatesField</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">get_lookup</span><span class=\"p\">(</span><span class=\"n\">lookup_name</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Anda kemudian akan menentukan <code class=\"docutils literal notranslate\"><span class=\"pre\">get_coordinate_lookup</span></code> dengan benar untuk mengembalikan sebuah subkelas <code class=\"docutils literal notranslate\"><span class=\"pre\">Lookup</span></code> yang menangani nilai yang terkait dari <code class=\"docutils literal notranslate\"><span class=\"pre\">dimension</span></code>.</p>\n<p>Ada cara yang dinamai mirip dipanggil <code class=\"docutils literal notranslate\"><span class=\"pre\">get_transform()</span></code>. <code class=\"docutils literal notranslate\"><span class=\"pre\">get_lookup()</span></code> harus selalu mengembalikan sebuah subkelas <code class=\"docutils literal notranslate\"><span class=\"pre\">Lookup</span></code>, dan <code class=\"docutils literal notranslate\"><span class=\"pre\">Lookup</span></code> sebuah subkelas <code class=\"docutils literal notranslate\"><span class=\"pre\">Transform</span></code>. Itu sangat penting diingat bahwa obyek <code class=\"docutils literal notranslate\"><span class=\"pre\">Transform</span></code> dapat lebih jauh disaring, dan obyek <code class=\"docutils literal notranslate\"><span class=\"pre\">Lookup</span></code> tidak dapat.</p>\n<p>Ketika menyaring, jika hanya ada satu nama pencarian tersisa untuk diselesaikan, kami akan mencari sebuah <code class=\"docutils literal notranslate\"><span class=\"pre\">Lookup</span></code>. Jika ada banyak nama, dia akan mencari sebuah <code class=\"docutils literal notranslate\"><span class=\"pre\">Transform</span></code>. Dalam keadaan dimana hanya ada satu nama dan sebuah <code class=\"docutils literal notranslate\"><span class=\"pre\">Lookup</span></code> tidak ditemukan, kami mencari sebuah <code class=\"docutils literal notranslate\"><span class=\"pre\">Transform</span></code> dan kemudian pencarian <code class=\"docutils literal notranslate\"><span class=\"pre\">exact</span></code> pada <code class=\"docutils literal notranslate\"><span class=\"pre\">Transform</span></code> tersebut. Semua panggilan selalu berurutan diakhiri dengan sebuah <code class=\"docutils literal notranslate\"><span class=\"pre\">Lookup</span></code>. Untuk menjelaskan:</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">.filter(myfield__mylookup)</span></code> akan memanggil <code class=\"docutils literal notranslate\"><span class=\"pre\">myfield.get_lookup('mylookup')</span></code>.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">.filter(myfield__mytransform__mylookup)</span></code> akan memanggil <code class=\"docutils literal notranslate\"><span class=\"pre\">myfield.get_transform('mytransform')</span></code>, dan lalu <code class=\"docutils literal notranslate\"><span class=\"pre\">mytransform.get_lookup('mylookup')</span></code>.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">.filter(myfield__mytransform)</span></code> akan memanggil pertama <code class=\"docutils literal notranslate\"><span class=\"pre\">myfield.get_lookup('mytransform')</span></code>, yang akan gagal, sehingga dia akan gagal kembali memanggil <code class=\"docutils literal notranslate\"><span class=\"pre\">myfield.get_transform('mytransform')</span></code> dan kemudian <code class=\"docutils literal notranslate\"><span class=\"pre\">mytransform.get_lookup('exact')</span></code>.</p></li>\n</ul>\n</section>","rootId":"custom-lookups","toc":[{"title":"Sebuah contoh pencarian sederhana","anchor":"a-simple-lookup-example","children":[]},{"title":"Contoh perubahan sederhana","anchor":"a-simple-transformer-example","children":[]},{"title":"Menulis sebuah pencarian abs__lt efisien","anchor":"writing-an-efficient-abs-lt-lookup","children":[]},{"title":"Sebuah contoh perubahan timbal balik","anchor":"a-bilateral-transformer-example","children":[]},{"title":"Menulis penerapan cara lain untuk pencarian yang ada","anchor":"writing-alternative-implementations-for-existing-lookups","children":[]},{"title":"Bagaimana Django menentuka pencarian dan merubah yang sedang digunakan","anchor":"how-django-determines-the-lookups-and-transforms-which-are-used","children":[]}],"breadcrumbs":[{"docname":"howto/index","title":"Panduan \"Bagaimana\"","url":"/id/1.9/howto/"}],"prev":{"docname":"howto/custom-model-fields","title":"Menulis bidang model penyesuaian","url":"/id/1.9/howto/custom-model-fields/"},"next":{"docname":"howto/custom-template-tags","title":"Penyesuaian etiket cetakan dan saringan","url":"/id/1.9/howto/custom-template-tags/"},"formats":{"html":"/id/1.9/howto/custom-lookups/","markdown":"/id/1.9/howto/custom-lookups.md","json":"/id/1.9/howto/custom-lookups.json"},"source":"https://github.com/django/django/blob/stable/1.9.x/docs/howto/custom-lookups.txt","official":"https://docs.djangoproject.com/id/1.9/howto/custom-lookups/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9"],"inLocales":["en","fr","ja","id","pt-br","es"]}