Seperti yang telah Anda ketahui, saya suka mengetik statis opsional. Masalahnya adalah bahwa kadang-kadang itu bukan opsional, tetapi tidak mungkin. Karena kami memiliki banyak proyek besar yang belum diketik dalam ekosistem Python.
Mereka berdua adalah Django dan Django-Rest-Framework. Apakah. Karena sekarang mereka bisa mengetik! Izinkan saya memperkenalkan organisasi drf
Django dan bertopik untuk django
dan drf
.
Ini akan menjadi tutorial ringkas dan panduan memulai.
Kudos
Saya ingin mengucapkan "terima kasih" yang besar kepada @mkurnikov karena memimpin proyek ini dan kepada semua kontributor yang memungkinkan ini terjadi. Anda semua luar biasa!
TLDR
Pada artikel ini, saya menunjukkan bagaimana tipe bekerja dengan django
dan drf
. Anda dapat melihat hasilnya di sini .
Dan Anda juga dapat menggunakan wemake-django-template
untuk memulai proyek baru Anda dengan semua yang sudah dikonfigurasi. Ini akan terlihat persis seperti contoh proyek.
Memulai
Dalam tutorial kecil ini, saya akan menunjukkan kepada Anda beberapa fitur django-stubs
dan djangorestframework-stubs
in action. Saya harap ini akan meyakinkan Anda bahwa memiliki seseorang untuk menggandakan periksa setelah Anda adalah hal yang baik.
Anda selalu dapat merujuk ke dokumentasi asli. Semua langkah juga tercakup di sana.
Untuk memulai kita akan memerlukan proyek baru dan lingkungan virtual yang bersih , sehingga kita dapat menginstal dependensi kita:
pip install django django-stubs mypy
Maka kita perlu mengkonfigurasi mypy
dengan benar. Itu dapat dibagi menjadi dua langkah. Pertama, kita mengkonfigurasi mypy
itu sendiri:
# setup.cfg [mypy] # The mypy configurations: https://mypy.readthedocs.io/en/latest/config_file.html python_version = 3.7 check_untyped_defs = True disallow_any_generics = True disallow_untyped_calls = True disallow_untyped_decorators = True ignore_errors = False ignore_missing_imports = True implicit_reexport = False strict_optional = True strict_equality = True no_implicit_optional = True warn_unused_ignores = True warn_redundant_casts = True warn_unused_configs = True warn_unreachable = True warn_no_return = True
Kemudian kita mengkonfigurasi plugin django-stubs
:
# setup.cfg [mypy] # Appending to `mypy` section: plugins = mypy_django_plugin.main [mypy.plugins.django-stubs] django_settings_module = server.settings
Apa yang kita lakukan di sini?
- Kami menambahkan plugin
mypy
khusus untuk membantu tipe menebak tipe checker di beberapa situasi spesifik Django yang rumit (seperti model, queryset, pengaturan, dll) - Kami juga menambahkan konfigurasi khusus untuk
django-stubs
untuk mengarahkannya ke pengaturan, kami gunakan untuk Django. Perlu mengimpornya.
Hasil akhirnya dapat ditemukan di sini .
Kami sekarang memiliki semua yang diinstal dan dikonfigurasi. Mari kita ketik periksa!
Mengecek tampilan
Mari kita mulai dengan mengetikkan pandangan karena ini adalah hal termudah untuk dilakukan dengan plugin ini.
Berikut tampilan sederhana berdasarkan fungsi kami:
Mari kita jalankan dan lihat jenis apa yang disadarinya. Perhatikan bahwa kami mungkin perlu memodifikasi PYTHONPATH
, sehingga mypy
dapat mengimpor proyek kami:
ยป PYTHONPATH="$PYTHONPATH:$PWD" mypy server server/apps/main/views.py:14: note: Revealed type is 'def () -> builtins.bool' server/apps/main/views.py:15: note: Revealed type is 'django.contrib.auth.models.User'
Mari kita coba hancurkan sesuatu:
Tidak, ada kesalahan ketik dan mypy
akan menangkapnya:
ยป PYTHONPATH="$PYTHONPATH:$PWD" mypy server server/apps/main/views.py:18: error: Argument 1 to "render" has incompatible type "Dict[str, Any]"; expected "HttpRequest"
Itu berhasil! Ok, tapi itu cukup mudah. Mari kita sedikit mempersulit contoh kita dan membuat model khusus untuk menunjukkan bagaimana kita bisa mengetik model dan queryset.
Mengetik model dan queryset
ORANG Django adalah fitur pembunuh. Ini sangat fleksibel dan dinamis. Ini juga berarti sulit untuk mengetik. Mari kita lihat beberapa fitur yang sudah dilindungi oleh django-stubs
.
Definisi model kami:
Dan setiap bidang model ini ditutupi oleh django-stubs
. Mari kita lihat jenis apa yang diungkapkan:
ยป PYTHONPATH="$PYTHONPATH:$PWD" mypy server server/apps/main/models.py:21: note: Revealed type is 'builtins.int*' server/apps/main/models.py:22: note: Revealed type is 'django.contrib.auth.models.User*' server/apps/main/models.py:23: note: Revealed type is 'builtins.str*' server/apps/main/models.py:24: note: Revealed type is 'builtins.bool*' server/apps/main/models.py:25: note: Revealed type is 'datetime.datetime*'
Semuanya terlihat bagus! django-stubs
menyediakan plugin mypy
khusus untuk mengubah bidang model menjadi tipe instance yang benar. Itu sebabnya semua tipe diungkapkan dengan benar.
Fitur besar kedua dari plugin django-stubs
adalah kita dapat mengetik QuerySet
:
Dan inilah cara memeriksa:
reveal_type(published_posts().first())
Kami bahkan dapat membuat anotasi kueri dengan .values()
dan .values_list()
. Plugin ini cerdas!
Saya telah berjuang dengan metode anotasi yang mengembalikan QuerySet
selama beberapa tahun. Fitur ini memecahkan masalah besar bagi saya: tidak ada lagi Iterable[BlogPost]
atau List[User]
. Sekarang saya bisa menggunakan tipe nyata.
Memeriksa jenis API
Tapi, mengetikkan pandangan, model, formulir, perintah, url, dan admin tidak semua yang kita miliki. TypedDjango juga memiliki typing untuk djangorestframework
. Mari kita instal dan konfigurasikan:
pip install djangorestframework djangorestframework-stubs
Dan kita bisa mulai membuat serializers:
Dilihat:
Dan router:
Bahkan tidak terlihat seperti sesuatu telah berubah, tetapi semua yang ada di dalamnya diketik: pengaturan, serializers, viewet, dan router. Ini akan memungkinkan Anda untuk menambahkan mengetik secara bertahap di mana Anda paling membutuhkannya.
Mari kita coba ubah queryset = BlogPost.objects.all()
to queryset = [1, 2, 3]
dalam tampilan kami:
ยป PYTHONPATH="$PYTHONPATH:$PWD" mypy server server/apps/main/views.py:25: error: Incompatible types in assignment (expression has type "List[int]", base class "GenericAPIView" defined the type as "Optional[QuerySet[Any]]")
Tidak, itu tidak akan berhasil! Perbaiki kode Anda!
Kesimpulan
Mengetik antarmuka kerangka kerja adalah hal yang luar biasa untuk dimiliki. Ketika dikombinasikan dengan alat-alat seperti returns
dan mappers
itu akan memungkinkan penulisan logika bisnis tipe-aman dan deklaratif yang dibungkus menjadi antarmuka kerangka kerja yang diketik. Dan untuk mengurangi jumlah kesalahan di lapisan antara keduanya.
Pengetikan statis bertahap opsional juga memungkinkan Anda untuk memulai dengan cepat dan menambahkan jenis hanya ketika API Anda distabilkan atau mengikuti pengembangan yang didorong oleh jenis sejak awal.
Namun, django-stubs
dan djangorestframework-stubs
adalah proyek baru. Masih ada banyak bug, fitur yang direncanakan, spesifikasi tipe yang hilang. Kami menyambut setiap kontribusi dari komunitas untuk membuat perkakas pengembang dengan Python benar-benar luar biasa.
Awalnya diterbitkan di blog saya .