Я разрабатываю веб-систему с Django / Python, и мне нужно определенное поле из модели User: CPF (https://en.wikipedia.org/wiki/Cadastro_de_Pessoas_Físicas). Мне нужно это с валидатором и для правильного форматированияперед вставкой в базу данных.
Я пытался использовать localflavor.br.forms.BRCPFField
из django-localflavor
и django-localflavor-br
(https://django -localflavor.readthedocs.io / en / latest / localflavor /br / ), но makemigrations
не может распознать новое поле, и migrate
не может обновить соответствующую таблицу в базе данных (я думаю, что это ошибка, но пока это не проблема). Итак, после рассмотрениядругие варианты, я решил попробовать и написать свой собственный валидатор.
РЕДАКТИРОВАТЬ 1: Код исправлен, как указано в моем комментарии к ответу Даниэля.
В models.py
:
from django.core.exceptions import ValidationError
def validate_cpf(cpf):
digitos = [int(digit) for digit in cpf if digit.isdigit()]
if len(digitos) < 11 or len(digitos) > 11:
raise ValidationError("Wrong number of digits")
sop = sum(a*b for a, b in zip(digitos[0:9], range(10, 1, -1)))
ed1 = (sop * 10 % 11) % 10
sop = sum(a*b for a, b in zip(digitos[0:10], range(11, 1, -1)))
ed2 = (sop * 10 % 11) % 10
if ed1 != digitos[9] or ed2 != digitos[10]:
raise ValidationError("Verification digits don't match")
else:
numeros = ''.join(str(d) for d in digitos)
return f'{numeros[0:3]}.{numeros[3:6]}.{numeros[6:9]}-{numeros[9:]}'
class Usuario(models.Model):
name = models.CharField(max_length=256)
cpf = models.CharField(max_length=14, validators=[validate_cpf])
В admin.py
:
from .models import Usuario
class UsuarioAdmin(admin.ModelAdmin):
fieldsets = [ ('ID', { 'fields': ['name', 'cpf', ], }), ]
list_display = ('name', 'cpf', )
admin.site.register(Usuario, UsuarioAdmin)
В области администрирования (http://localhost:8000/admin/), я могу без проблем добавить нового пользователя.письменный валидатор также отлично работает:
23755124050
принято. 237.551.240-50
принято. +-*23755124050
илидопускается какая-либо другая мыслимая строка с этими 11 цифрами в данном конкретном порядке. 237.551.240-51
не принимается: («Контрольные цифры не совпадают») 37.551.240-50
не принято: («Неверное количество цифр»)
Итак, валидатор работает нормально.
РЕДАКТИРОВАТЬ 2: Текст исправлен после первого редактирования.
Проблема в том, что когда я сохраняю его в базе данных, я хочу - независимо от регистра ввода (1) в (3) - сохранить в формате: f'{numeros[0:3]}.{numeros[3:6]}.{numeros[6:9]}-{numeros[9:]}'
.Но база данных всегда сохраняет введенный текст как заданный до проверки (учитывая введенный текст как проверенный).Таким образом, +-*23755124050
сохраняется как есть, а не как 237.551.240-50
, как я намереваюсь.
Это сложно для меня, я упускаю что-то важное в этом процессе.Кто-нибудь может просветить меня?