Ketika menerapkan metode otentikasi baru dan memanggil tampilan dengan izin IsAuthenticated dan pengguna tidak diautentikasi, kerangka istirahat Django memunculkan:
File "XXX/site-packages/rest_framework/views.py", line 206, in check_permissions
self.permission_denied(request)
File "XXX/site-packages/rest_framework/views.py", line 80, in permission_denied
if not self.request.successful_authenticator:
File "XXX/site-packages/rest_framework/request.py", line 362, in __getattr__
return getattr(self._request, attr)
AttributeError: 'WSGIRequest' object has no attribute 'successful_authenticator'
Melihat kode, saya pikir tidak benar. Di mana " self.request
.successful_authenticator" menurut saya seharusnya " request
.successful_authenticator".
Views.py, dekat baris 80.
def permission_denied(self, request):
"""
If request is not permitted, determine what kind of exception to raise.
"""
if not self.request.successful_authenticator:
raise exceptions.NotAuthenticated()
raise exceptions.PermissionDenied()
Maaf, saya membuat kesalahan yang sama dalam kode saya!!!
Bagi siapa pun yang sampai pada masalah ini melalui Google...
Petunjuk ke sumber kesalahan adalah ia mengatakan WSGIRequest
tidak memiliki atribut successful_authenticator
. Tetapi pada titik ini dalam kode DRF kita harus berurusan dengan rest_framework.request.Request
daripada WSGIRequest
telanjang.
Dan sebenarnya jika Anda memasukkan kode melalui pdb, Anda mungkin akan menemukan bahwa Anda memiliki permintaan DRF daripada WSGIRequest kosong.
Masalahnya adalah request.Request
memiliki sejumlah @property
metode yang didekorasi (seperti user
, successful_authenticator
dan lainnya) tetapi juga memiliki __getattr__
metode.
Apa yang terjadi adalah: jika kode di salah satu properti memicu AttributeError
maka Python akan memanggil metode __getattr__
sebagai gantinya, yang pada akhirnya mencoba menemukan attr (dengan nama yang sama dengan properti yang errored) pada objek WSGIRequest
.
Begitulah cara Anda mendapatkan kesalahan seperti 'WSGIRequest' object has no attribute 'successful_authenticator'
atau 'WSGIRequest' object has no attribute 'user'
(yang terakhir hanya jika Anda tidak menggunakan Django AuthenticationMiddleware tentunya).
Dalam kasus saya, AttributeError berasal dari salah satu authentication_classes
... yang dipanggil secara bergantian saat pertama kali Anda mengakses properti @successful_authenticator
. Kombinasi properti dan __getattr__
pada kelas Permintaan secara efektif menutupi sumber kesalahan yang sebenarnya.
Jalankan ke dalamnya ketika tampilan DRF kami memiliki authentication_classes
tidak tepat (secara tidak sengaja, kelas auth lawas untuk kerangka kerja rest api lainnya). Semoga suatu hari python menjadi typesafe :)
FYI, jika Anda menggunakan DRF dengan djangorestframework-expiring-authtoken
< 0.1.4
maka Anda akan melihat kesalahan ini, yang disebabkan oleh masalah berikut:
https://github.com/JamesRitchie/Django-rest-framework-expiring-tokens/issues/11
Komentar yang paling membantu
Bagi siapa pun yang sampai pada masalah ini melalui Google...
Petunjuk ke sumber kesalahan adalah ia mengatakan
WSGIRequest
tidak memiliki atributsuccessful_authenticator
. Tetapi pada titik ini dalam kode DRF kita harus berurusan denganrest_framework.request.Request
daripadaWSGIRequest
telanjang.Dan sebenarnya jika Anda memasukkan kode melalui pdb, Anda mungkin akan menemukan bahwa Anda memiliki permintaan DRF daripada WSGIRequest kosong.
Masalahnya adalah
request.Request
memiliki sejumlah@property
metode yang didekorasi (sepertiuser
,successful_authenticator
dan lainnya) tetapi juga memiliki__getattr__
metode.Apa yang terjadi adalah: jika kode di salah satu properti memicu
AttributeError
maka Python akan memanggil metode__getattr__
sebagai gantinya, yang pada akhirnya mencoba menemukan attr (dengan nama yang sama dengan properti yang errored) pada objekWSGIRequest
.Begitulah cara Anda mendapatkan kesalahan seperti
'WSGIRequest' object has no attribute 'successful_authenticator'
atau'WSGIRequest' object has no attribute 'user'
(yang terakhir hanya jika Anda tidak menggunakan Django AuthenticationMiddleware tentunya).Dalam kasus saya, AttributeError berasal dari salah satu
authentication_classes
... yang dipanggil secara bergantian saat pertama kali Anda mengakses properti@successful_authenticator
. Kombinasi properti dan__getattr__
pada kelas Permintaan secara efektif menutupi sumber kesalahan yang sebenarnya.