Исключение поля из валидации 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? screenshot

Если вы установите пользовательскую форму, вы можете манипулировать вводом данных в форму до их сохранения в БД, а также определять тип данных для ввода.

Редактирование: чтобы сделать то, что я сказал, вы можете в конечном итоге удалить пользовательский ввод и просто сделать *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)

К сожалению, я не могу разработать полный ответ для вашего случая, но надеюсь, что эти примеры помогут вам начать поиск решения.

Вернуться на верх