Saat mengerjakan proyek Django, ada sejumlah perpustakaan pihak ketiga yang harus dimiliki jika Anda tidak ingin menemukan kembali roda tanpa henti. Alat untuk men-debug kueri sql (debug-toolbar, silk, --print-sql dari django-extensions), sesuatu untuk menyimpan struktur pohon, tugas periodik/ditangguhkan (omong-omong, uswgi memiliki antarmuka seperti cron . EAV masih diperlukan , meskipun sering dapat digantikan oleh jsonfield. Dan salah satu hal yang sangat berguna ini, tetapi untuk beberapa alasan yang kurang sering dibahas di internet adalah FSM. Untuk beberapa alasan saya tidak sering menemukannya di kode orang lain.
Hampir setiap record dalam database memiliki beberapa status. Misalnya untuk sebuah komentar, bisa - diterbitkan / dihapus / dihapus oleh moderator. Untuk memesan di toko - dikeluarkan / dibayar / dikirim / dikembalikan, dll. Selain itu, transisi dari satu keadaan ke keadaan lain sering dioleskan di atas kode dan ada logika bisnis di dalamnya, yang harus banyak ditutupi dengan tes (Anda masih harus melakukannya, tetapi Anda dapat menghindari pengujian hal-hal dasar, misalnya, bahwa pesanan bisa masuk ke status "refund" hanya setelah dalam kondisi "dibayar".
Akan sangat logis untuk menggambarkan transisi semacam itu secara lebih deklaratif dan di satu tempat. Seiring dengan logika yang diperlukan dan verifikasi akses.
Berikut adalah contoh kode dari tes perpustakaan Django-fsm
class BlogPost(models.Model):
"""
Test workflow
"""
state = FSMField(default='new', protected=True)
def can_restore(self, user):
return user.is_superuser or user.is_staff
@transition(field=state, source='new', target='published',
on_error='failed', permission='testapp.can_publish_post')
def publish(self):
pass
@transition(field=state, source='published')
def notify_all(self):
pass
@transition(field=state, source='published', target='hidden', on_error='failed',)
def hide(self):
pass
@transition(
field=state,
source='new',
target='removed',
on_error='failed',
permission=lambda self, u: u.has_perm('testapp.can_remove_post'))
def remove(self):
raise Exception('No rights to delete %s' % self)
@transition(field=state, source='new', target='restored',
on_error='failed', permission=can_restore)
def restore(self):
pass
@transition(field=state, source=['published', 'hidden'], target='stolen')
def steal(self):
pass
@transition(field=state, source='*', target='moderated')
def moderate(self):
pass
class Meta:
permissions = [
('can_publish_post', 'Can publish post'),
('can_remove_post', 'Can remove post'),
]
Ini bagus untuk api istirahat, antara lain. Kita dapat membuat titik akhir untuk transisi antar status secara otomatis. Misalnya, permintaan / pesanan / id / pembatalan terlihat seperti tindakan logis yang sempurna untuk sebuah viewset. Dan kami sudah memiliki informasi yang diperlukan untuk memverifikasi akses! Dan juga untuk tombol di panel admin, dan kemampuan untuk menggambar bagan yang indah dengan alur kerja :) Bahkan ada editor alur kerja visual, mis. non-programmer dapat menggambarkan proses bisnis
Semakin banyak kode deklaratif dan generik yang kita tulis, semakin dapat diandalkan. Lebih sedikit kode, lebih sedikit duplikasi, lebih sedikit bug. Pengujian sebagian dialihkan ke penulis perpustakaan, dan Anda dapat fokus pada logika bisnis yang unik untuk proyek tersebut.