Исключение поля из валидации Django в форме администратора
Я работаю над проектом с большим количеством унаследованной кодовой базы (Django 2.2). У меня есть пользовательское поле модели для цены, которое выглядит следующим образом
class PriceField(PositiveIntegerField):
def get_prep_value(self, value: float) -> Optional[int]:
return int(value * 100) if value else self.default
def from_db_value(self, value: int, expression, connection) -> Optional[float]:
return value / 100 if value else value
class Expertise(models.Model):
price = PriceField(blank=True, default=0, help_text='Price per min.')
...
Цены хранятся в базе данных, умноженные на 100, например, 9.90 хранится как 990, а значения получаются из базы данных в человекочитаемом виде (990 как 9.90).
Теперь я столкнулся с проблемой валидации по умолчанию PositiveIntegerField Django административной формы для этого поля. Поскольку это значение представлено как float каждый раз, когда я нажимаю кнопку "Сохранить", я получаю PositiveIntegerField'ValidationError.
Есть ли способ исключить это поле из валидации формы администратора или отправить значение этого поля, умноженное на 100?

Если вы установите пользовательскую форму, вы можете манипулировать вводом данных в форму до их сохранения в БД, а также определять тип данных для ввода.
Редактирование: чтобы сделать то, что я сказал, вы можете в конечном итоге удалить пользовательский ввод и просто сделать *100 на пользовательской форме, в любом случае, я думаю, что если вы хотите игнорировать валидацию, ответ может быть в пользовательской форме.
Раньше у меня была пользовательская форма следующего вида:
class ArticleModelForm(forms.ModelForm):
project = forms.ModelChoiceField(
queryset=Project.objects.order_by('title'),
label="Proyecto",
empty_label="Seleccionar proyecto",
widget=forms.Select(
attrs={
"class": "basic-single form-control w-100",
"id": "id-select-project-article"
}))
//lot more inputs
def __init__(self, *args, **kwargs):
super(ArticleModelForm, self).__init__(*args, **kwargs)
self.fields['image'].widget.attrs['class'] = 'form-control-file'
self.fields['image'].widget.attrs['accept'] = 'image/*'
self.fields['file'].widget.attrs['class'] = 'form-control-file'
self.fields['file'].widget.attrs['accept'] = 'application/pdf'
for field in self.fields.values():
field.error_messages = {
'required':
'El campo {fieldname} es requerido'.format(
fieldname=field.label)
}
def clean_file(self):
file = self.cleaned_data.get("file")
if not (file.name.endswith(".pdf")):
raise forms.ValidationError(
"Favor de ingresar un archivo en formato pdf")
return file
def clean_project(self):
project = self.cleaned_data.get("project")
user = self.cleaned_data.get("user")
if project:
projectObj = Project.objects.get(id=project.id)
if not user in projectObj.participants.all():
raise forms.ValidationError(
"Usted no es participante en este proyecto.")
return project
class Meta:
model = Article
fields = [
'user', 'project', 'journal', 'authors', 'title', 'indexed',
'indexInfo', 'arbitration', 'publicationYear', 'pages', 'file',
'image', 'programTribute', 'academyTribute', 'eventPublication',
'tags'
]
Вы можете сделать свою логику, чтобы *100 ваше число на чистом методе для поля и вернуть это значение для сохранения.
Я не помню точно, как установить пользовательские формы в админке, но я точно знаю, что вы можете это сделать.
Я знаю, что я сделал это для установки пользовательской модели пользователя и должен был импортировать мои пользовательские формы в admin.py моего приложения users:
from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from .forms import UserSapCreationForm, UserSapChangeForm //my custom forms
from .models import UserSap
class UserSapAdmin(UserAdmin):
add_form = UserSapCreationForm
form = UserSapChangeForm
model = UserSap
verbose_name = 'Usuario Sap'
list_display = (
'email',
'account',
'rol',
'is_staff',
'is_active',
)
list_filter = (
'rol',
'is_staff',
'is_active',
)
fieldsets = (
('Usuario Sap', {
'fields': (
'email',
'password',
'rol',
)
}),
('Informacion personal', {
'fields': ('account', )
}),
('Grupos', {
'classes': ('wide', ),
'fields': ('groups', )
}),
('Permisos', {
'classes': ('wide', ),
'fields': ('user_permissions', )
}),
('Login', {
'fields': ('is_active', )
}),
('Staff', {
'fields': ('is_staff', )
}),
)
"""
add_fieldsets = (
('add', {
'classes': ('wide',),
'fields': ('email', 'account', 'rol', 'password1', 'password2', 'is_staff', 'is_active')}
),
)
"""
ordering = ('email', )
search_fields = ('email', )
filter_horizontal = ()
admin.site.register(UserSap, UserSapAdmin)
К сожалению, я не могу разработать полный ответ для вашего случая, но надеюсь, что эти примеры помогут вам начать поиск решения.