Saya mencoba request.user untuk metode bersih formulir, tapi bagaimana saya bisa mengakses objek permintaan? Dapatkah saya mengubah metode bersih untuk mengizinkan input variabel?
99
Jawaban oleh Ber - menyimpannya di threadlocals - adalah ide yang sangat buruk. Sama sekali tidak ada alasan untuk melakukannya dengan cara ini.
Cara yang jauh lebih baik adalah mengganti metode formulir __init__
untuk mengambil argumen kata kunci tambahan request
,. Ini menyimpan permintaan dalam bentuk , jika diperlukan, dan dari mana Anda dapat mengaksesnya dalam metode bersih Anda.
class MyForm(forms.Form):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(MyForm, self).__init__(*args, **kwargs)
def clean(self):
... access the request object via self.request ...
dan menurut pandangan Anda:
myform = MyForm(request.POST, request=request)
DIPERBARUI 25/10/2011 : Saya sekarang menggunakan ini dengan kelas yang dibuat secara dinamis daripada metode, karena Django 1.3 menampilkan beberapa keanehan sebaliknya.
Kemudian timpa
MyCustomForm.__init__
sebagai berikut:Anda kemudian dapat mengakses objek permintaan dari metode apa pun
ModelForm
denganself.request
.sumber
__new__
kwargs yang nantinya akan diteruskan ke metode kelas__init__
. Penamaan kelasModelFormWithRequest
menurut saya jauh lebih jelas dalam maknanya daripadaModelFormMetaClass
.Untuk apa nilainya, jika Anda menggunakan Tampilan Berbasis Kelas , alih-alih tampilan berbasis fungsi, timpa
get_form_kwargs
dalam tampilan pengeditan Anda. Contoh kode untuk CreateView kustom :Kode tampilan di atas akan
request
tersedia sebagai salah satu argumen kata kunci untuk__init__
fungsi konstruktor formulir . Karena itu dalam pekerjaan AndaModelForm
:sumber
request
objekget_form_kwargs
secara otomatis.self.get_object
? TheCreateView
memperpanjangSingleObjectMixin
. Tetapi apakah ini berfungsi atau memunculkan pengecualian bergantung pada apakah Anda membuat objek baru atau memperbarui yang sudah ada; yaitu menguji kedua kasus (dan tentu saja penghapusan).Pendekatan biasa adalah menyimpan objek permintaan dalam referensi lokal-thread menggunakan middleware. Kemudian Anda bisa mengakses ini dari mana saja di aplikasi Anda, termasuk metode Form.clean ().
Mengubah tanda tangan dari metode Form.clean () berarti Anda memiliki versi Django yang telah Anda modifikasi, yang mungkin bukan yang Anda inginkan.
Terima middleware count terlihat seperti ini:
Daftarkan middleware ini seperti yang dijelaskan dalam dokumen Django
sumber
**kwargs
, yang berarti Anda harus meneruskan objek permintaan sebagaiMyForm(request.POST, request=request)
.Untuk admin Django, di Django 1.8
sumber
Saya mengalami masalah khusus ini saat menyesuaikan admin. Saya ingin bidang tertentu divalidasi berdasarkan kredensial admin tertentu.
Karena saya tidak ingin mengubah tampilan untuk meneruskan permintaan sebagai argumen ke formulir, berikut ini yang saya lakukan:
sumber
obj=obj
tidakobj=None
di baris 11.'function' object has no attribute 'base_fields'
. Namun, jawaban @ François yang lebih sederhana (tanpa penutupan) bekerja dengan lancar.Anda tidak dapat selalu menggunakan metode ini (dan mungkin praktiknya yang buruk), tetapi jika Anda hanya menggunakan formulir dalam satu tampilan, Anda dapat mencakupnya di dalam metode tampilan itu sendiri.
sumber
get_form_class
metode CBV , jika saya tahu saya perlu melakukan banyak hal dengan permintaan tersebut. Mungkin ada beberapa overhead dalam membuat kelas berulang kali, tetapi itu hanya memindahkannya dari waktu impor ke waktu proses.Jawaban Daniel Roseman masih yang terbaik. Namun, saya akan menggunakan argumen posisi pertama untuk permintaan tersebut, bukan argumen kata kunci karena beberapa alasan:
Terakhir, saya akan menggunakan nama yang lebih unik untuk menghindari menimpa variabel yang ada. Jadi, jawaban saya yang dimodifikasi terlihat seperti:
sumber
keju segar dari cheesebaker @ pypi: django-requestprovider
sumber
Saya punya jawaban lain untuk pertanyaan ini sesuai kebutuhan Anda, Anda ingin mengakses pengguna ke metode bersih formulir. Anda bisa mencoba ini. View.py
forms.py
Sekarang Anda dapat mengakses self.instance dalam metode bersih apa pun di form.py
sumber
Ketika Anda ingin mengaksesnya melalui tampilan kelas Django yang "disiapkan" seperti
CreateView
ada trik kecil untuk diketahui (= solusi resmi tidak bekerja di luar kotak). Di Anda sendiri,CreateView
Anda harus menambahkan kode seperti ini:= singkatnya ini adalah solusi untuk meneruskan
request
ke formulir Anda dengan tampilan Buat / Perbarui Django.sumber