如果值为 None,Django 管理员更改视图排除字段
Django admin change view exclude field if value is None
目前我需要从更改视图中删除一些字段,如果它的值为 None
所以我有一个提款模型的管理员,如下所示:
class WithdrawalsAdminForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(WithdrawalsAdminForm, self).__init__(*args, **kwargs)
none_fields = []
for single_field in self.fields:
self.fields[single_field].disabled = True
if self.initial[single_field] == None:
none_fields.append(single_field)
if none_fields:
for single_none_field in none_fields:
self.fields.pop(single_none_field)
class WithdrawalsAdmin(admin.ModelAdmin):
list_display = ('get_email', 'get_phone_number', 'currency', 'method', 'amount', 'status', 'created')
list_display_links = ('get_email', 'get_phone_number', 'currency', 'method', 'amount', 'status', 'created')
list_filter = [WithdrawalsStatusFilter] #just a custom list filter
change_form_template = 'admin/backend/withdrawals_change_form.html'
form = WithdrawalsAdminForm
fields = (
'id',
'get_email',
'get_phone_number',
'get_full_name',
'currency',
'method',
'to_bank',
'to_address',
'to_card',
'amount',
'status',
'transaction_id',
'created',
'submitted',
'confirmed',
)
readonly_fields = (
'id',
'get_email',
'get_phone_number',
'get_full_name',
'created',
)
def has_add_permission(self, request, obj=None):
return False
def get_queryset(self, request):
qs = super(WithdrawalsAdmin, self).get_queryset(request)
return qs.filter(Q(method=1) | Q(method=4))
def get_email(self, obj):
return obj.user.email
get_email.short_description = 'User email'
get_email.admin_order_field = 'EMAIL'
def get_phone_number(self, obj):
return obj.user.phone_number
get_phone_number.short_description = 'User phone number'
get_phone_number.admin_order_field = 'PHONE NUMBER'
def get_full_name(self, obj):
try:
user_kyc = UserKyc.objects.get(user=obj.user)
return decrypt_string(user_kyc.full_name)
except:
return None
get_full_name.short_description = 'User full name'
get_full_name.admin_order_field = 'FULL NAME'
admin.site.register(Withdrawals, WithdrawalsAdmin)
但它返回给我以下错误:
"Key 'to_address' not found in 'WithdrawalsForm'. Choices are: amount,
currency, method, status, to_bank."
数量、货币、方法、状态,to_bank在对象
中都没有None的值
to_address 值为 None,我还尝试打印出 if self.initial[single_field] == None:
中 none 的任何字段并获得正确的字段名称(包括 to_address 在其中)具有 None 值。
如何从更改视图中排除具有 None 值的字段?
您可能想要重写 get_fields 和 get_readonly_fields 方法:
def _get_non_field_names(self, obj, candidate_fields):
for field in candidate_fields:
if hasattr(obj, field) and getattr(obj, field):
yield field
elif getattr(self, field)(obj):
yield field
def get_fields(self, request, obj=None):
form = self._get_form_for_get_fields(request, obj)
candidate_fields = self.fields if self.fields else list(form.base_fields)
fields = self._get_non_field_names(obj, candidate_fields)
readonly_fields = list(self.get_readonly_fields(request, obj))
return list(fields) + readonly_fields
def get_readonly_fields(self, request, obj=None):
candidate_readonly_fields = self.readonly_fields
readonly_fields = list(self._get_non_field_names(obj, candidate_readonly_fields))
return readonly_fields
困难的部分仍然是检查自定义字段的 None 值。
目前我只使用下面的get_fields来检查,不太合乎逻辑,但仍然可以从表单中删除字段:
def get_fields(self, request, obj=None):
fields = super(WithdrawalsAdmin, self).get_fields(request, obj)
fields_list = list(fields)
if obj:
if obj.to_address is None:
fields_list.remove('to_address')
.... #and other fields
fields_tuple = tuple(fields_list)
return fields_tuple
目前我需要从更改视图中删除一些字段,如果它的值为 None
所以我有一个提款模型的管理员,如下所示:
class WithdrawalsAdminForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(WithdrawalsAdminForm, self).__init__(*args, **kwargs)
none_fields = []
for single_field in self.fields:
self.fields[single_field].disabled = True
if self.initial[single_field] == None:
none_fields.append(single_field)
if none_fields:
for single_none_field in none_fields:
self.fields.pop(single_none_field)
class WithdrawalsAdmin(admin.ModelAdmin):
list_display = ('get_email', 'get_phone_number', 'currency', 'method', 'amount', 'status', 'created')
list_display_links = ('get_email', 'get_phone_number', 'currency', 'method', 'amount', 'status', 'created')
list_filter = [WithdrawalsStatusFilter] #just a custom list filter
change_form_template = 'admin/backend/withdrawals_change_form.html'
form = WithdrawalsAdminForm
fields = (
'id',
'get_email',
'get_phone_number',
'get_full_name',
'currency',
'method',
'to_bank',
'to_address',
'to_card',
'amount',
'status',
'transaction_id',
'created',
'submitted',
'confirmed',
)
readonly_fields = (
'id',
'get_email',
'get_phone_number',
'get_full_name',
'created',
)
def has_add_permission(self, request, obj=None):
return False
def get_queryset(self, request):
qs = super(WithdrawalsAdmin, self).get_queryset(request)
return qs.filter(Q(method=1) | Q(method=4))
def get_email(self, obj):
return obj.user.email
get_email.short_description = 'User email'
get_email.admin_order_field = 'EMAIL'
def get_phone_number(self, obj):
return obj.user.phone_number
get_phone_number.short_description = 'User phone number'
get_phone_number.admin_order_field = 'PHONE NUMBER'
def get_full_name(self, obj):
try:
user_kyc = UserKyc.objects.get(user=obj.user)
return decrypt_string(user_kyc.full_name)
except:
return None
get_full_name.short_description = 'User full name'
get_full_name.admin_order_field = 'FULL NAME'
admin.site.register(Withdrawals, WithdrawalsAdmin)
但它返回给我以下错误:
"Key 'to_address' not found in 'WithdrawalsForm'. Choices are: amount, currency, method, status, to_bank."
数量、货币、方法、状态,to_bank在对象
中都没有None的值to_address 值为 None,我还尝试打印出 if self.initial[single_field] == None:
中 none 的任何字段并获得正确的字段名称(包括 to_address 在其中)具有 None 值。
如何从更改视图中排除具有 None 值的字段?
您可能想要重写 get_fields 和 get_readonly_fields 方法:
def _get_non_field_names(self, obj, candidate_fields):
for field in candidate_fields:
if hasattr(obj, field) and getattr(obj, field):
yield field
elif getattr(self, field)(obj):
yield field
def get_fields(self, request, obj=None):
form = self._get_form_for_get_fields(request, obj)
candidate_fields = self.fields if self.fields else list(form.base_fields)
fields = self._get_non_field_names(obj, candidate_fields)
readonly_fields = list(self.get_readonly_fields(request, obj))
return list(fields) + readonly_fields
def get_readonly_fields(self, request, obj=None):
candidate_readonly_fields = self.readonly_fields
readonly_fields = list(self._get_non_field_names(obj, candidate_readonly_fields))
return readonly_fields
困难的部分仍然是检查自定义字段的 None 值。
目前我只使用下面的get_fields来检查,不太合乎逻辑,但仍然可以从表单中删除字段:
def get_fields(self, request, obj=None):
fields = super(WithdrawalsAdmin, self).get_fields(request, obj)
fields_list = list(fields)
if obj:
if obj.to_address is None:
fields_list.remove('to_address')
.... #and other fields
fields_tuple = tuple(fields_list)
return fields_tuple