Seperti yang ditanyakan judul, mengapa orang-orang Django memutuskan untuk mengimplementasikan objek request.POST dengan querydict (yang, tentu saja, pada gilirannya, membuat semuanya tidak dapat diubah?)
Saya tahu Anda dapat memutifikasinya dengan membuat salinan data posting
post = request.POST.copy()
tapi kenapa melakukan ini? Tentunya akan lebih mudah jika membiarkan hal itu berubah? Atau apakah itu digunakan untuk beberapa alasan lain juga yang mungkin menyebabkan masalah?
request.POST
telah dikirimkan dengan lebih banyak data daripada yang sebenarnya.Jawaban:
Ini sedikit misteri, bukan? Beberapa teori yang dangkal masuk akal ternyata salah dalam penyelidikan:
Sehingga
POST
objek tersebut tidak harus menerapkan metode mutasi? Tidak:POST
objek milikdjango.http.QueryDict
kelas , yang menerapkan set lengkap metode mutasi termasuk__setitem__
,__delitem__
,pop
danclear
. Ini mengimplementasikan kekekalan dengan memeriksa tanda ketika Anda memanggil salah satu metode mutasi. Dan saat Anda memanggilcopy
metode, Anda mendapatkanQueryDict
instance lain dengan flag yang bisa berubah diaktifkan.Untuk peningkatan kinerja? Tidak:
QueryDict
kelas tidak mendapatkan keuntungan kinerja saat tanda yang bisa berubah dimatikan.Sehingga
POST
objek tersebut dapat digunakan sebagai kunci kamus? Tidak:QueryDict
objek tidak dapat di-hash.Sehingga
POST
data dapat dibangun dengan malas (tanpa berkomitmen untuk membaca keseluruhan respon), seperti diklaim di sini ? Saya tidak melihat bukti ini dalam kode: sejauh yang saya tahu, seluruh respon selalu dibaca, baik secara langsung , atau melaluiMultiPartParser
untukmultipart
tanggapan.Untuk melindungi Anda dari kesalahan pemrograman? Saya telah melihat klaim ini, tetapi saya belum pernah melihat penjelasan yang baik tentang apa kesalahan ini, dan bagaimana kekekalan melindungi Anda dari kesalahan tersebut.
Dalam hal apapun,
POST
ini tidak selalu berubah : ketika responmultipart
, makaPOST
bisa berubah. Ini tampaknya menempatkan omong kosong pada sebagian besar teori yang mungkin Anda pikirkan. (Kecuali jika perilaku ini merupakan pengawasan.)Singkatnya, saya tidak dapat melihat alasan yang jelas di Django untuk
POST
objek menjadi tidak berubah untuk non-multipart
permintaan.sumber
Jika permintaan adalah hasil dari
form
penyerahan Django , maka masuk akal bagi POSTimmutable
untuk memastikan integritas data antara penyerahan formulir dan validasi formulir . Bagaimanapun, jika permintaan tidak dikirim melaluiform
penyerahan Django , maka POST adalahmutable
karena tidak ada validasi formulir.Anda selalu dapat melakukan sesuatu seperti ini: (sesuai komentar @ leo-the-manic )
sumber
Pembaruan :
Gareth Rees benar bahwa poin 1 & 3 tidak valid dalam kasus ini. Meskipun menurut saya poin 2 dan 4 masih berlaku, oleh karena itu saya akan meninggalkan tesis di sini.
(Saya perhatikan bahwa
request.POST
objek Pyramid (Pylon) dan Django adalah beberapa bentukMultiDict
. Jadi mungkin ini adalah praktik yang lebih umum daripada membuatrequest.POST
kekal.)Saya tidak dapat berbicara untuk orang-orang Django, meskipun bagi saya tampaknya bisa karena beberapa alasan berikut:
Pertunjukan . objek yang tidak dapat diubah "lebih cepat" daripada objek yang bisa berubah karena memungkinkan pengoptimalan yang substansial. Sebuah objek tidak dapat diubah artinya kita dapat mengalokasikan ruang untuknya pada waktu pembuatan , dan persyaratan ruang tidak berubah. Ia juga memiliki hal-hal seperti efisiensi penggandaan dan efisiensi perbandingan karenanya.Sunting : ini tidak terjadiQueryDict
seperti yang ditunjukkan Gareth Rees.request.POST
, tampaknya tidak ada aktivitas di sisi server yang perlu mengubah data permintaan . Dan karenanya, objek yang tidak dapat diubah lebih cocok, belum lagi mereka memiliki keunggulan performa yang substansial.Objek tak berubah bisa digunakan sebagaiEdit : kesalahan saya, tak bisa diubah tidak secara langsung menyiratkan hashable ; objek yang dapat di- hash , bagaimanapun, biasanya juga tidak dapat diubah .dict
kunci, yang saya kira bisa sangat berguna di suatu tempat di Django ..request.POST
(terutama ke plugin pihak ketiga dan keluar), Anda dapat berharap bahwa objek permintaan dari pengguna ini tidak akan berubah.Dalam beberapa hal, alasan ini juga merupakan jawaban umum untuk "tidak berubah vs bisa berubah?" pertanyaan. Saya yakin ada lebih banyak pertimbangan desain daripada di atas dalam kasus Django.
sumber
sessions
cara hidup singkat untuk mendapatkan dan memodifikasi data antar status.POST
adalah sebuahQueryDict
objek , dan objek-objek ini tidak mendapatkan keuntungan performa karena tidak dapat diubah. Dan poin Anda (3) tidak bisa menjadi jawabannya, karenaQueryDict
objek tidak dapat di-hash, sehingga tidak bisa digunakan sebagai kunci kamus.QueryDict
sebelum saya menjawab.requests.POST._mutable = True; requests.POST['foo'] = 'bar'; request.POST._mutable = False
Saya suka itu tidak dapat diubah secara default. Seperti yang ditunjukkan, Anda dapat membuatnya berubah jika perlu, tetapi Anda harus menjelaskannya secara eksplisit. Ini seperti 'Saya tahu bahwa saya dapat membuat formulir saya men-debug mimpi buruk tetapi saya tahu apa yang saya lakukan sekarang.'
sumber
Saya menemukan ini di komentar di Stack Answer https://stackoverflow.com/a/2339963
sumber
Harap dicatat:
multipart
permintaan tidak dapat diubah sejak Django 1.11 https://github.com/django/django/blob/stable/1.11.x/django/http/multipartparser.py#L292Mereka bisa berubah di versi sebelumnya.
sumber