class BooksFilter(filters.FilterSet):
class Meta:
model = Books
Saat menghilangkan opsi fields
di kelas filterset (seperti di atas), semua bidang model akan disertakan dalam filterset. Hal ini dapat menyebabkan kebocoran informasi saat digunakan bersama dengan DRF, di mana formulir dirender dalam API yang dapat dijelajahi.
Baik Django dan DRF memerlukan bidang untuk ditetapkan secara eksplisit dalam bentuk/serializer karena potensi masalah keamanan. Ini harus diperlukan dalam filterset Django-filter juga.
http://www.django-rest-framework.org/api-guide/serializers/#specifying -which-fields-to-include
https://docs.djangoproject.com/en/1.10/topics/forms/modelforms/#selecting -the-fields-to-use
Saya senang untuk berkontribusi dengan PR atau menjelaskan lebih lanjut tentang situasi di mana hal ini dapat menyebabkan kebocoran informasi, jika diperlukan.
@nip3o Yap. Senang melihat ini.
Saya juga ingin bidang memerlukan filter yang dideklarasikan, sesuai DRF, saat Anda melakukannya...
btw - kebocoran data sebagian diatasi oleh #451. Saat ini Anda akan melihat peringatan penghentian tentang perilaku yang tidak ditentukan/berubah. Di 1.0, perilaku baru adalah Meta.fields
atau Meta.fields = None
yang tidak ada tidak melakukan apa-apa.
Saya juga ingin bidang memerlukan filter yang dideklarasikan, sesuai DRF, saat Anda melakukannya
Saya tidak yakin bagaimana ini akan bekerja dengan sintaks dict untuk Meta.fields
. misalnya:
class UserFilter(filters.FilterSet):
username = filters.CharFilter()
class Meta:
model = User
fields = {
'name': ['contains', 'startswith', 'endswith', ...'],
???
}
Saya tidak yakin bagaimana ini akan bekerja dengan sintaks dict
Memang.
Saya masih agak :-1: dalam hal ini. Saya tidak melihat cara untuk menyelesaikan sintaks dict Meta.fields
dengan filter yang dideklarasikan. Setidaknya, tidak dengan cara yang tidak canggung:
class UserFilter(filters.FilterSet):
username = filters.CharFilter(name='username', lookup_expr='exact')
username_like = filters.CharFilter(name='username', lookup_expr='icontains')
relevance = filters.CharFilter(method='filter_relevance')
class Meta:
model = User
fields = {
'name': ['contains', 'startswith', 'endswith', ...'],
'username': ['exact'], # match w/ the lookup_expr?
'username_like': ['icontains'],
'relevance': [???] # What about method filters?
}
Selain itu, persyaratan ini mengalami masalah untuk bidang model khusus yang tidak mewarisi kelas bidang yang ditemukan di FilterSet.FILTER_DEFAULTS
. Bidang khusus akan membutuhkan yang berikut:
class NetworkSettingFilter(FilterSet):
mask = MaskFilter(...)
class Meta:
model = NetworkSetting
fields = ['mask']
filter_overrides = {
SubnetMaskField: {'filter_class': MaskFilter},
}
# vs.
class NetworkSettingFilter(FilterSet):
mask = MaskFilter(...)
class Meta:
model = NetworkSetting
Catatan tambahan: poin selanjutnya ini adalah sesuatu yang _bisa_ kami perbaiki. Kita harus menulis ulang pembuatan otomatis untuk berperilaku seperti pembuat serial DRF alih-alih seperti bentuk model Django. Either way, perhatian utama saya adalah konflik sintaks.
OKE. Mari kita tinggalkan untuk saat ini.
Saya suka proposal aslinya. Saya cenderung membatasinya ke _Jika fields
adalah daftar..._ Tapi saya perlu memikirkannya sedikit lagi.
Sedikit bolak-balik tetapi saya akan membuat tonggak ulang ini hanya untuk masalah aslinya .
Baik fields
atau exclude
harus dideklarasikan. fields = '__all__'
harus minimal.
(Tidak memaksakan bahwa daftar cocok adalah sesuatu yang bisa kita kembalikan.)
Kode DRF yang relevan ada di sini :
assert not (fields is None and exclude is None), (
"Creating a ModelSerializer without either the 'fields' attribute "
"or the 'exclude' attribute has been deprecated since 3.3.0, "
"and is now disallowed. Add an explicit fields = '__all__' to the "
"{serializer_class} serializer.".format(
serializer_class=self.__class__.__name__
),
)
Kami membutuhkan tambahan serupa di filters_for_model
:
# Setting exclude with no fields implies all other fields.
if exclude is not None and fields is None:
fields = ALL_FIELDS
Itu harus ditinggalkan untuk memulai.
Baik
fields
atauexclude
harus dideklarasikan.fields = '__all__'
harus minimal.
Saya pasti bisa berada di belakang itu. Saat ini sedang mengerjakan PR.
Dingin.
Berpikir tentang, jangan khawatir tentang depresiasi. Ini adalah perubahan kecil, pada perubahan versi besar. Pastikan untuk menyebutkannya di catatan perubahan. 👍🏽
Berpikir tentang, jangan khawatir tentang depresiasi. Ini adalah perubahan kecil, pada perubahan versi besar. Pastikan untuk menyebutkannya di catatan perubahan.
Tujuannya sedikit berbeda, tetapi kami sebenarnya membahasnya di sini .
Juga, saat ini memfaktorkan ulang filters_for_model
untuk tidak mencoba pembuatan filter untuk filter yang dideklarasikan. (Ini relevan dengan contoh subnet/mask di mana fields = ['mask']
akan memunculkan pengecualian yang tidak perlu.
Ditutup oleh #550
Komentar yang paling membantu
btw - kebocoran data sebagian diatasi oleh #451. Saat ini Anda akan melihat peringatan penghentian tentang perilaku yang tidak ditentukan/berubah. Di 1.0, perilaku baru adalah
Meta.fields
atauMeta.fields = None
yang tidak ada tidak melakukan apa-apa.