O Django possui vários campos numéricos disponíveis para uso em modelos, por exemplo, DecimalField e PositiveIntegerField . Embora o primeiro possa ser restrito ao número de casas decimais armazenadas e ao número geral de caracteres armazenados, existe alguma maneira de restringi-lo a armazenar apenas números dentro de um determinado intervalo, por exemplo, 0,0-5,0?
Caso contrário, existe alguma maneira de restringir um PositiveIntegerField para armazenar apenas, por exemplo, números de até 50?
Atualização: agora que o Bug 6845 foi fechado , esta questão do StackOverflow pode ser discutida. - sampablokuper
python
django
django-models
numbers
sampablokuper
fonte
fonte
Respostas:
Você também pode criar um tipo de campo de modelo personalizado - consulte http://docs.djangoproject.com/en/dev/howto/custom-model-fields/#howto-custom-model-fields
Nesse caso, você pode 'herdar' do IntegerField interno e substituir sua lógica de validação.
Quanto mais penso nisso, percebo o quanto isso seria útil para muitos aplicativos Django. Talvez um tipo IntegerRangeField possa ser enviado como um patch para os desenvolvedores do Django considerarem adicionar ao tronco.
Isso está funcionando para mim:
Em seguida, na sua classe de modelo, você a usaria assim (o campo é o módulo onde você coloca o código acima):
OU para uma faixa de negativo e positivo (como uma faixa do oscilador):
O que seria muito legal é se ele pudesse ser chamado com o operador de intervalo assim:
Mas, isso exigiria muito mais código, já que você pode especificar um parâmetro 'skip' - range (1, 50, 2) - embora seja interessante ...
fonte
MinValueValidator(min_value) and MaxValueValidator(max_value)
antes de chamarsuper().__init__ ...
(snippet: gist.github.com/madneon/147159f46ed478c71d5ee4950a9d697d )Você pode usar os validadores embutidos do Django -
Editar : Ao trabalhar diretamente com o modelo, chame o método full_clean do modelo antes de salvar o modelo para acionar os validadores. Isso não é necessário ao usar,
ModelForm
pois os formulários farão isso automaticamente.fonte
null=True
eblank=True
funciona conforme o esperado. O campo é opcional e, se for deixado em branco, será armazenado como nulo.fonte
Eu tive esse mesmo problema; aqui estava a minha solução:
fonte
models.IntegerField(choices=[(i, i) for i in range(1, n)], blank=True)
Existem duas maneiras de fazer isso. Uma é usar a validação de formulário para nunca permitir que um número acima de 50 seja inserido por um usuário. Documentos de validação de formulário .
Se não houver usuário envolvido no processo ou você não estiver usando um formulário para inserir dados, será necessário substituir o
save
método do modelo para lançar uma exceção ou limitar os dados que entram no campo.fonte
Aqui está a melhor solução, se você deseja alguma flexibilidade extra e não deseja alterar seu campo de modelo. Basta adicionar este validador personalizado:
E pode ser usado como tal:
Os dois parâmetros são max e min, e permite nulos. Você pode personalizar o validador, se quiser, se livrando da instrução if marcada ou alterar seu campo para ficar em branco = Falso, nulo = Falso no modelo. É claro que isso exigirá uma migração.
Nota: Eu tive que adicionar o validador porque o Django não valida o intervalo no PositiveSmallIntegerField; em vez disso, ele cria um smallint (no postgres) para esse campo e você recebe um erro de banco de dados se o numérico especificado estiver fora do intervalo.
Espero que isso ajude :) Mais sobre Validadores no Django .
PS. Baseei minha resposta no BaseValidator em django.core.validators, mas tudo é diferente, exceto o código.
fonte