---
title: "Como criar campos de modelo customizado"
version: 4.2
locale: pt-br
source: https://docs.djangoproject.com/pt-br/4.2/howto/custom-model-fields/
canonical: https://djangodocs.dev/pt-br/4.2/howto/custom-model-fields/
---
# Como criar campos de modelo customizado

## Introdução

A documentação [referência de modelo](/pt-br/4.2/topics/db/models/) explica como usar as classes de campo padrão do Django –[`CharField`](/pt-br/4.2/ref/models/fields/#django.db.models.CharField), [`DateField`](/pt-br/4.2/ref/models/fields/#django.db.models.DateField), etc. Para muitos propósitos, essas classes são tudo o que você irá precisar. Às vezes, porém, a versão do Django não irá atender às suas necessidades específicas, ou você irá querer usar um campo que é totalmente diferente daqueles fornecidos com Django.

Os tipos de campos embutidos no Django não cobrem todas os possíveis tipos de colunas do banco de dados – somente os tipos comuns, tais como ```VARCHAR``e ``INTEGER```. Para tipos de colunas mais obscuros, tal como polígonos geográficos ou ainda tipos criados pelo usuário como , é possível definir sua própria subclasse de `Field` do Django.

Por outro lado, pode haver um tipo complexo de objeto no Python que pode de alguma maneira ser serializado para que se encaixe em um tipo de coluna padrão no banco de dados. Este é um outro caso onde uma subclasse de `Field` pode ajudar a utilizar o objeto com o “models”.

### Nosso objeto de exemplo

Criar campos personalizados requer um pouco de atenção. Para que seja mais fácil de acompanhar, usaremos um exemplo consistente através desta documentação: um objeto Python que represente a coleção de cartas de uma mão de [Bridge](https://en.wikipedia.org/wiki/Contract_bridge). Não se preocupe, não é necessário saber como jogar Bridge para entender o exemplo. É necessário saber que 52 cartas são distribuídas igualmente para 4 jogadores, os quais são tradicionalmente chamados *north* (norte), *east* (leste), *south* (sul) and *west* (oeste). Nossa classe se parece com isso:

```
class Hand:
    """A hand of cards (bridge style)"""

    def __init__(self, north, east, south, west):
        # Input parameters are lists of cards ('Ah', '9s', etc.)
        self.north = north
        self.east = east
        self.south = south
        self.west = west

    # ... (other possibly useful methods omitted) ...
```

Isto é uma classe Python ordinária, com nada específico voltado ao Django. Nós gostamos de poder fazer coisas como essa em nossos modelos ( assumimos que o atributo `hand` no modelo é um instância de `Hand`):

```
example = MyModel.objects.get(pk=1)
print(example.hand.north)

new_hand = Hand(north, east, south, west)
example.hand = new_hand
example.save()
```

Atribuimos ou lemos o valor do atributo `hand` no nosso modelo como em qualquer outra classe Python. Este truque é para dizer ao Django como manipular a gravação e a leitura como um objeto.

Para utilizar a classe `Hand` em nossos modelos, nós **não** precisamos alterar essa classe em nada. Isso é ideal, porque quer dizer que podemos facilmente escrever modelos de suporte para classes existentes cujo o código fonte não pode ser alterado.

> **Note**
>
> Você pode estar querendo tirar vantagem dos tipos customizados de colunas de banco de dados e lidar com o dado como um tipo de dado Python padrão nos seus modelos; Este caso é similar ao nosso exemplo `Hand`  e iremos explicitar qualquer diferença enquanto continuamos.

## A teoria por trás.

### Armazenamento no Banco de Dados.

Vamos começar com campos de modelo. Se você decompô-lo, um campo de modelo fornece uma maneira de pegar um objeto Python normal – string, boolean, `datetime` ou algo mais complexo como `Hand` – e convertê-lo de e para um formato que é útil quando se lida com o banco de dados. (Esse formato também é útil para serialização, mas como veremos mais adiante, isso é mais fácil quando você tem o lado do banco de dados sob controle).

Campos em um modelo devem ser de alguma maneira convertidos para que se encaixem em um tipo de coluna de banco de dados já existente. Bancos de dados diferentes provêem diferentes tipos de colunas, mas a regra ainda é a mesma: aqueles são os únicos dados que se tem para trabalhar. Qualquer coisa que se queira guardar em um banco de dados deve se encaixar em um daqueles tipos.

Normalmente, você está escrevendo um campo Django para corresponder a um determinado tipo de coluna de banco de dados ou precisará de uma maneira de converter seus dados em, digamos, uma string.

Para nosso exemplo de `Mão`, poderíamos converter os dados do cartão em uma string de 104 caracteres concatenando todos os cartões juntos em uma ordem predeterminada – digamos, todos os cartões do *norte* primeiro, depois o *leste*, \* sul\* e *oeste*. Assim, os objetos `Mão` podem ser salvos em colunas de texto ou caracteres no banco de dados.

### O que uma classe campo faz?

Todos os campos do Django (e quando dizemos *campo* neste documento, sempre queremos dizer campos do modelo e não [campos de forms](/pt-br/4.2/ref/forms/fields/)) são subclasses de [`django.db.models.Field`](/pt-br/4.2/ref/models/fields/#django.db.models.Field). A maioria das informações que o Django registra sobre um campo é comum a todos os campos –name, help text, uniqueness e por diante. Armazenar toda essa informação é papel de `Field`. Iremos entrar em detalhes precisos do que o `Field` pode fazer mais tarde; por agora, basta dizer que tudo descende de `Field` e então customizamos partes chaves do comportamento da classe.

É importante dizer que a classe de campo do Django não é o que é armazenado no seus atributos do modelo. Os atributos dos modelos contém objetos Python normais. As classes de campo que são definidas em um modelo são na verdade armazenadas dentro da classe `Meta` quando a classe é criada (os detalhes precisos de como isso é feito são importantes aqui). Isso é porque as classes de campos não são necessárias enquanto se está modificando atributos. Na verdade, eles fornecem o maquinário para conversão entre o valor do atributo e o que é armazenado no banco de dados ou enviado para o [serializador](/pt-br/4.2/topics/serialization/).

Tenha isso em mente ao criar seus próprios campos. A subclasse `Field` do Django que você escreve provê o maquinário para conversão entre suas instancias Python e os valores do banco de dados/serializador de várias maneiras (existe uma diferença entre armazenar um valor e usar um valor para lookups por exemplo). Se isso lhe soa um pouco confuso, não se preocupe – se tornará claro no exemplo abaixo. Mas lembre que muitas vezes acabará por criar duas classes quando quiser um campo personalizado:

- A primeira classe é o objeto Python que os usuários irão manipular. Irão assinalar isso a um atributo de model, lerão para mostrar, coisas assim. Esta é a classe `Hand` em nosso exemplo.
- A segunda classe é a subclasse `Field`. Essa é a classe que sabe como converter sua classe entre sua forma de armazenamento permanente e a forma do Python e vice-versa.

## Escrevendo uma subclasse de campo

Quando estiver panejando sua subclasse de [`Field`](/pt-br/4.2/ref/models/fields/#django.db.models.Field), primeiro de uma com qual classe já existente [`Field`](/pt-br/4.2/ref/models/fields/#django.db.models.Field) seu campo se parece mais. É possível fazer uma subclasse de campo Django já existente  e economizar algum trabalho ? Caso não, você deve construir uma subclasse de [`Field`](/pt-br/4.2/ref/models/fields/#django.db.models.Field), da qual tudo descende.

Iniciar seu novo campo é uma questão de separar quaisquer argumentos que são específicos para seu caso dos argumentos comuns e passar este último para o método `__init__()` da [`Field`](/pt-br/4.2/ref/models/fields/#django.db.models.Field) (ou sua classe pai).

No nosso exemplo, iremos chamar nosso campo de `HandField`. (é uma boa idéia chamar sua subclasse [`Field`](/pt-br/4.2/ref/models/fields/#django.db.models.Field)  `<AgumaCoisa>Field`, então ela fica facilmente identificável como uma subclasse de  [`Field`](/pt-br/4.2/ref/models/fields/#django.db.models.Field)) . Nosso campo não se comporta como nenhum outro campo existente, então iremos herdar diretamente de  [`Field`](/pt-br/4.2/ref/models/fields/#django.db.models.Field):

```
from django.db import models

class HandField(models.Field):
    description = "A hand of cards (bridge style)"

    def __init__(self, *args, **kwargs):
        kwargs["max_length"] = 104
        super().__init__(*args, **kwargs)
```

Nosso `HandField` aceita a maioria das opções dos campos padrão (veja a lista abaixo), mas asseguramos que ele tenha um comprimento fixo, já que só precisa de 52 valores de carta mais seus naipes; 104 caracteres no total.

> **Note**
>
> Muitos dos campos de modelo do Django aceitam opções com as quais não fazem nada. Por exemplo, você pode passar [`editable`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.editable) e [`auto_now`](/pt-br/4.2/ref/models/fields/#django.db.models.DateField.auto_now) para um `django.db.models. DateField` e irá ignorar o parâmetro [`editable`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.editable) ([`auto_now`](/pt-br/4.2/ref/models/fields/#django.db.models.DateField.auto_now) sendo definido implica `editable=False`) . Nenhum erro é levantado neste caso.
>
> Esse comportamento simplifica as classes de campo, pois não precisam verificar opções desnecessárias. Eles passam todas as opções para a classe pai e não as usam mais tarde. Cabe a você decidir se deseja que seus campos sejam mais rígidos sobre as opções selecionadas ou se deseja usar o comportamento mais permissivo dos campos atuais.

O método `Field.__init__()` recebe os seguintes parâmetros:

- [`verbose_name`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.verbose_name)
- `name`
- [`primary_key`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.primary_key)
- [`max_length`](/pt-br/4.2/ref/models/fields/#django.db.models.CharField.max_length)
- [`unique`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.unique)
- [`blank`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.blank)
- [`null`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.null)
- [`db_index`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.db_index)
- `rel`: Usado para campos relacionados (como [`ForeignKey`](/pt-br/4.2/ref/models/fields/#django.db.models.ForeignKey)). Somente para uso avançado.
- [`default`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.default)
- [`editable`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.editable)
- `serialize`: se `False`, o campo não será “serializado” quando o modelo for passado para os  [serializadores](/pt-br/4.2/topics/serialization/). Padrão é `True`.
- [`unique_for_date`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.unique_for_date)
- [`unique_for_month`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.unique_for_month)
- [`unique_for_year`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.unique_for_year)
- [`choices`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.choices)
- [`help_text`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.help_text)
- [`db_column`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.db_column)
- [`db_tablespace`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.db_tablespace): Somente para a criação de índice, se o “backend” suportar [tablespaces](/pt-br/4.2/topics/db/tablespaces/). Normalmente é possível ignorar essa opção.
- [`auto_created`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.auto_created): `True` se o campo foi criado automaticamente, como para o [`OneToOneField`](/pt-br/4.2/ref/models/fields/#django.db.models.OneToOneField) usado pela herança de modelo. Somente para uso avançado.

Todas as opções sem uma explicação na lista acima tem o mesmo significado que os campos normais do Django. veja a [field documentation](/pt-br/4.2/ref/models/fields/) para exemplos e detalhes.

### A descontrução do Campo

O contraponto para escrever seu método `__init__()` é escrever o método [`deconstruct()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.deconstruct). É usado durante model migrations \` para dizer ao Django como pegar uma instância de seu novo campo e reduzi-lo a um formato serializado - em particular, quais argumentos passar para \`\`\_\_init\_\_()\` para recriá-lo.

Se não foram adicionadas opções extras ao campo que foi herdado, então não há necessidade de reescrever o método `deconstruct()`. Por outro lado,  se você mudar os argumentos passados no `__init__()` (como em `HandField`), será preciso complementar os argumentos sendo passados.

`deconstruct()` retorna uma tupla de quatro itens: o nome do atributo do campo, o caminho de importação completo da classe do campo, os argumentos posicionais (como uma lista) e os argumentos da palavra-chave (como um dict). Note que isso é diferente do método `deconstruct()` :ref:para classes customizadas \` que retorna uma tupla de três coisas.

Como autor do campo customizado, não é necessário se preocupar sobre os dois primeiros valores; a classe `Field` básica tem todo o código para o atributo “name” e “import path” funcionar. Entretanto, devemos nos preocupar com o argumentos posicionais e os nomeados, já que estes são as alterações que fizemos

Por exemplo, na nossa classe “HandField” sempre somos forçados a definir max\_length em “ \_\_init \_\_ () “. O método “deconstruct()”  da classe base “Field” ierá tentar retornar os argumentos da palavra-chave; assim, podemos lançar a partir dos argumentos palavras-chaves para facilitar a leitura

```
from django.db import models

class HandField(models.Field):
    def __init__(self, *args, **kwargs):
        kwargs["max_length"] = 104
        super().__init__(*args, **kwargs)

    def deconstruct(self):
        name, path, args, kwargs = super().deconstruct()
        del kwargs["max_length"]
        return name, path, args, kwargs
```

Se você adicionar um novo argumento chave, você vai precisar escrever código em `deconstruct()` que põe o valor dentro de `kwargs` você mesmo. Você deveria também omitir o valor de `kwargs` quando ele não é necessário para reconstruir o estado do campo, como quando se usa o valor padrão:

```
from django.db import models

class CommaSepField(models.Field):
    "Implements comma-separated storage of lists"

    def __init__(self, separator=",", *args, **kwargs):
        self.separator = separator
        super().__init__(*args, **kwargs)

    def deconstruct(self):
        name, path, args, kwargs = super().deconstruct()
        # Only include kwarg if it's not the default
        if self.separator != ",":
            kwargs["separator"] = self.separator
        return name, path, args, kwargs
```

Exemplos mais complexos estão além do escopo deste documento, mas lembre - para qualquer configuração da sua instância de Field, o `deconstruct()` tem que retornar argumentos que se possa passar para o `__init__` para reconstruir aquele estado.

Preste atenção extra se foram definidos novos valores padrão para argumentos na superclasse do `Field`, tem que ter certeza de que estes são sempre incluídos, ao invés de desaparecer se recebem o valor antigo.

Além disso, evite retornar valores como argumentos posicionais; sempre que possível, retorne valores como argumentos de palavra-chave para máxima compatibilidade futura. Se você alterar os nomes das coisas com mais frequência do que sua posição na lista de argumentos do construtor, talvez prefira posicional, mas tenha em mente que as pessoas estarão reconstruindo seu campo a partir da versão serializada por um bom tempo (possivelmente anos), dependendo de quanto tempo suas migrações vivem.

Você pode ver os resultados da desconstrução observando as migrações que incluem o campo e pode testar a desconstrução em testes de unidade desconstruindo e reconstruindo o campo:

```
name, path, args, kwargs = my_field_instance.deconstruct()
new_instance = MyField(*args, **kwargs)
self.assertEqual(my_field_instance.some_attribute, new_instance.some_attribute)
```

### Atributos de campo que não afetam a definição da coluna do banco de dados

> **New in Django 4.1**

Você pode substituir `Field.non_db_attrs` para personalizar os atributos de um campo que não afetam a definição de uma coluna. É usado durante as migrações do modelo para detectar operações `AlterField` no-op.

Por exemplo:

```
class CommaSepField(models.Field):
    @property
    def non_db_attrs(self):
        return super().non_db_attrs + ("separator",)
```

### Alterando a classe básica de um campo personalizado

Você não pode alterar a classe base de um campo personalizado porque o Django não irá detectar a mudança, e não irá fazer uma migração para ele. Por exemplo, se você começar com:

```
class CustomCharField(models.CharField):
    ...
```

e decidir que quer usar um `TextFeld` no lugar, você não pode mudar a classe base como estea aqui:

```
class CustomCharField(models.TextField):
    ...
```

Ao invés, você deve criar uma nova classe de campo personalizado e atualizar seu modelo para referenciá-la.

```
class CustomCharField(models.CharField):
    ...

class CustomTextField(models.TextField):
    ...
```

Como discutido em [removendo campos](/pt-br/4.2/topics/migrations/#migrations-removing-model-fields), você deve manter a classe `CustomCharField` original enquanto tiver migrações que façam referência a ela.

### Documentando o seu campo customizado

Como sempre, você deve documentar seu tipo de campo, para que os usuários saibam o que é. Além de fornecer uma docstring para ele, que é útil para desenvolvedores, você também pode permitir que os usuários do aplicativo admin vejam uma breve descrição do tipo de campo por meio do aplicativo django.contrib.admindocs \`. Para fazer isso, forneça um texto descritivo em um atributo de classe :attr:\`~Field.description de seu campo personalizado. No exemplo acima, a descrição exibida pelo aplicativo `admindocs` para um `HandField` será ‘Uma mão de cartas (estilo bridge)’.

No display do [`django.contrib.admindocs`](/pt-br/4.2/ref/contrib/admin/admindocs/#module-django.contrib.admindocs), a descrição do campo é interpolada com `field.__dict__` o qual habilita a descrição incorporar argumentos do campo. Por exemplo, a descrição para [`CharField`](/pt-br/4.2/ref/models/fields/#django.db.models.CharField) é:

```
description = _("String (up to %(max_length)s)")
```

### Métodos úteis

Uma vez criada a subclasse de [`Field`](/pt-br/4.2/ref/models/fields/#django.db.models.Field), você deve considerar sobrescrever um poucos métodos, dependendo do comportamento do seu campo. A lista de métodos abaixo está mais ou menos em uma ordem decrescente de importância, então comece do topo.

#### Tipos de banco de dados personalizados

Vamos dizer que você tenha criado um tipo personalizado para o PostgreSQL chamado `mytype`. Você pode herdar de `Field` e implementar o método [`db_type()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.db_type), como a:

```
from django.db import models

class MytypeField(models.Field):
    def db_type(self, connection):
        return "mytype"
```

Uma vez que tenha `MyTypeField`, pode usá-lo em qualquer modelo, tal como qualquer outro tipo `Field`:

```
class Person(models.Model):
    name = models.CharField(max_length=80)
    something_else = MytypeField()
```

Se você deseja criar um aplicativo independente de banco de dados, deve considerar as diferenças nos tipos de colunas. Por exemplo, o tipo de coluna de data/hora no PostgreSQL é chamado “timestamp”, enquanto a mesma coluna no MySQL é chamada “datetime”. Você pode lidar com isso em um método [`db_type()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.db_type)  verificando o atributo “connection.vendor”. Os fornecedores integrados atuais são: “sqlite”, “postgresql”, “mysql” e “oracle”.

Por exemplo:

```
class MyDateField(models.Field):
    def db_type(self, connection):
        if connection.vendor == "mysql":
            return "datetime"
        else:
            return "timestamp"
```

The [`db_type()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.db_type) and [`rel_db_type()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.rel_db_type) methods are called by
Django when the framework constructs the `CREATE TABLE` statements for your
application – that is, when you first create your tables. The methods are also
called when constructing a `WHERE` clause that includes the model field –
that is, when you retrieve data using QuerySet methods like `get()`,
`filter()`, and `exclude()` and have the model field as an argument.

Alguns tipos de coluna do banco de dados aceitam parâmetros, como `CHAR(25)`, onde o parâmetro `25` representa o tamanho máximo da coluna. Em casos como este, é mais flexível se o parâmetro for especificado no modelo ao invés de ser hard-coded no método `db_type()`. Por exemplo, não faria muito sentido  ter  `CharMaxlength25Field`, mostrado aqui:

```
# This is a silly example of hard-coded parameters.
class CharMaxlength25Field(models.Field):
    def db_type(self, connection):
        return "char(25)"

# In the model:
class MyModel(models.Model):
    # ...
    my_field = CharMaxlength25Field()
```

O melhor jeito de fazer isso seria fazer o parâmetro ser especificado em tempo de execução – isto é, quando a classe é instanciada. Para fazer isso, basta implementar `Field.__init__()`, como em:

```
# This is a much more flexible example.
class BetterCharField(models.Field):
    def __init__(self, max_length, *args, **kwargs):
        self.max_length = max_length
        super().__init__(*args, **kwargs)

    def db_type(self, connection):
        return "char(%s)" % self.max_length

# In the model:
class MyModel(models.Model):
    # ...
    my_field = BetterCharField(25)
```

Finalmente, se sua coluna requer uma configuração SQL realmente complexa, retorne `None` do [`db_type()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.db_type). Isso irá fazer que o código de criação de SQL do Django ignore este campo. Então você é responsável por criar a coluna na tabela correta de alguma outra maneira, mas isso é uma maneira de dizer ao Django para sair do caminho.

O método [`rel_db_type()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.rel_db_type) é chamado por campos como o  `ForeignKey` e o `OneToOneField` que apontam para outros campos para determinar o tipo da sua coluna de banco de dados. Por exemplo, se tiver um `UnsignedAutoField`, você também precisa de chaves estrangeiras que apontam para aquele campo para usar o mesmo tipo de dado:

```
# MySQL unsigned integer (range 0 to 4294967295).
class UnsignedAutoField(models.AutoField):
    def db_type(self, connection):
        return "integer UNSIGNED AUTO_INCREMENT"

    def rel_db_type(self, connection):
        return "integer UNSIGNED"
```

#### Convertendo valores para objetos Python

Se sua classe customizada de [`Field`](/pt-br/4.2/ref/models/fields/#django.db.models.Field) lida com estruturas de dados mais complexas que  strings, datas, inteiros, or floats, então talvez precise sobrescrever o [`from_db_value()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.from_db_value) e [`to_python()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.to_python).

Se presente para a subclasse do campo, `from_db_value()` será chamado em todas as circunstâncias quando dados são lidos do banco de dados, incluindo em agregacões e chamadas do [`values()`](/pt-br/4.2/ref/models/querysets/#django.db.models.query.QuerySet.values) .

o `to_python()` é chamado pela deserialização e durante o método [`clean()`](/pt-br/4.2/ref/models/instances/#django.db.models.Model.clean) usado nos forms.

Como regra geral, to\_python()\`\`deve lidar tranquilamente com qualquer dos seguintes argumentos:

- Uma instância do tipo correto (ex., Hand\`\`no nosso exemplo corrente).
- Uma string
- ```None``(se o campo permitir ``null=True```)

Na nossa classe `HandField`, estamos armazendo os dados como campo VARCHAR no banco de dados, então precisamos ser capazes de processar strings e `None` no `from_db_value()`. No `to_python()`, precisamos também lidar com instâncias de `Hand`:

```
import re

from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import gettext_lazy as _

def parse_hand(hand_string):
    """Takes a string of cards and splits into a full hand."""
    p1 = re.compile(".{26}")
    p2 = re.compile("..")
    args = [p2.findall(x) for x in p1.findall(hand_string)]
    if len(args) != 4:
        raise ValidationError(_("Invalid input for a Hand instance"))
    return Hand(*args)

class HandField(models.Field):
    # ...

    def from_db_value(self, value, expression, connection):
        if value is None:
            return value
        return parse_hand(value)

    def to_python(self, value):
        if isinstance(value, Hand):
            return value

        if value is None:
            return value

        return parse_hand(value)
```

Perceba que sempre retornamos uma instância destes métodos. Este é o tipo do objeto Python que queremos armazenar no atributo do modelo.

Para `to_python()`, se qualquer coisa der errado durante a conversão do valor, deve-se gerar a exceção [`ValidationError`](/pt-br/4.2/ref/exceptions/#django.core.exceptions.ValidationError).

#### Convertendo objetos Python para valores em queries

Uma vez que usar um banco de dados requer conversão em ambos os sentidos, se você sobrescrever [`to_python()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.to_python) é necessário sobrescrever também [`get_prep_value()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.get_prep_value) para converter os objetos Python de novo em valores de query.

Por exemplo:

```
class HandField(models.Field):
    # ...

    def get_prep_value(self, value):
        return "".join(
            ["".join(l) for l in (value.north, value.east, value.south, value.west)]
        )
```

> **Warning**
>
> Caso seu campo personalizado use os tipos `CHAR`, `VARCHAR` or `TEXT` parao MySQL, assegure que o [`get_prep_value()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.get_prep_value) sempre retorne um tipo string. O MySQL responde a pesquisa de maneira variável e inesperada quando uma query é executada com estes tipos e o valor fornecido é um inteiro, o que pode resultar em queries qeu contenham objetos inesperados nos seus resultados. Este problema não pode ocorrer se sempre retornar um tipo string do [`get_prep_value()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.get_prep_value).

#### Convertendo valores de queries para valores de banco de dados

Alguns tipos de dados (por exemplo datas) precisam estar em um formato específico antes deles poderem ser usados por um “backend” de banco de dados. O [`get_db_prep_value()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.get_db_prep_value) é um método onde estas conversões devem ser feitas. A conexão específica que será usada para a query é passada pelo parâmetro `connection`. Isso lhe possibilita usar a lógica de conversão espeçifica para um backend se isso for necessário.

Por exemplo, o Django usa o seguinte método para isso [`BinaryField`](/pt-br/4.2/ref/models/fields/#django.db.models.BinaryField):

```
def get_db_prep_value(self, value, connection, prepared=False):
    value = super().get_db_prep_value(value, connection, prepared)
    if value is not None:
        return connection.Database.Binary(value)
    return value
```

No caso do seu campo personalizado precisar de uma conversão especial quando for salvo e isso não é o mesmo que a conversão usada para parâmetros de query, você pode sobrescrever [`get_db_prep_save()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.get_db_prep_save).

#### Processando valores antes de salvar

Caso queira processar o valor logo antes de salvar, pode-se usar [`pre_save()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.pre_save). Por exemplo, o [`DateTimeField`](/pt-br/4.2/ref/models/fields/#django.db.models.DateTimeField) do Django usa este método para definir o atributo corretamente no caso de [`auto_now`](/pt-br/4.2/ref/models/fields/#django.db.models.DateField.auto_now)  ou [`auto_now_add`](/pt-br/4.2/ref/models/fields/#django.db.models.DateField.auto_now_add).

Caso sobrescreva este método, é necessário retornar o valor do atributo no fim. Deve-se também atualizar o atributo do modelo caso tenham sido feito mudanças no valor, de modo que que o código que mantém as referências ao modelo sempre veja o valor correto.

#### Especificando o campo de um formulário para o campo de um modelo.

Para personalizar o campo de formulário usado pelo [`ModelForm`](/pt-br/4.2/topics/forms/modelforms/#django.forms.ModelForm), você pode sobrescrever [`formfield()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.formfield).

A classe do campo de formulário pode ser especificada via o `form_class` e os argumentos de  `choices_form_class`; o último é especificado se o campo tiver opções (choices) especificadas, do contrário o primeiro. Se estes argumentos não são fornecidos, será usada a [`CharField`](/pt-br/4.2/ref/forms/fields/#django.forms.CharField) ou [`TypedChoiceField`](/pt-br/4.2/ref/forms/fields/#django.forms.TypedChoiceField).

Todos os dicionários `kwargs` é passado diretamente para o método \_\_init\_\_()\` do campo do formulário. Normalmente, tudo o que você precisa fazer é definir um bom padrão para o argumento do  `form_class` (e talvez `choices_form_class`) e delegar futuras manipulações para a classe pai. Isso talvez requeira que seja escrito um campo de form personalizado (e mesmo o widget de formulário). Veja o [forms documentation](/pt-br/4.2/topics/forms/) para informações sobre isso.

Continuando nosso exemplo em andamento, podemos escrever o método [`formfield()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.formfield)  como:

```
class HandField(models.Field):
    # ...

    def formfield(self, **kwargs):
        # This is a fairly standard way to set up some defaults
        # while letting the caller override them.
        defaults = {"form_class": MyFormField}
        defaults.update(kwargs)
        return super().formfield(**defaults)
```

Isso assume que importamos uma classe de campo `MyModelField` (o qual tem seu próprio widget padrão). Este documento não cobre os detalhes de escrever um campo de formulário personalizado.

#### Emulando tipos de campos internos.

Se você criou um método [`db_type()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.db_type), não precisa se preocupar sobre  [`get_internal_type()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.get_internal_type) – isso não será usado muito. As vezes, porém, seu armazenamento no banco de dados é similar em tipo a outro campo, então você pode usar a lógica deste outro campo para criar a coluna correta.

Por exemplo:

```
class HandField(models.Field):
    # ...

    def get_internal_type(self):
        return "CharField"
```

Não importa qual backend de banco de dados que esteja sendo usado, isso quer dizer que  o [`migrate`](/pt-br/4.2/ref/django-admin/#django-admin-migrate) e outros comandos SQL criam o tipo de coluna correto para armazenar uma string.

Se o [`get_internal_type()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.get_internal_type)  retorna uma string que não é conhecida para o Django para o backend de banco de dados que está sendo usado – que é, ele não aparece no  `django.db.backends.<db_name>.base.DatabaseWrapper.data_types` – a string ainda será usada pelo serializador, mas o método padrão [`db_type()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.db_type) retornará `None`. Veja a documentação do [`db_type()`](/pt-br/4.2/ref/models/fields/#django.db.models.Field.db_type) pelas razões pelas quais este talvez seja útil.

#### Convertendo dado do campo para serialização

Para personalizar como os valores são serializados por um serializador, você pode sobrescrever :meth:’~Field.value\_to\_string’. Utilizando :meth:’~Field.value\_from\_object’ é a melhor forma para obter o valor dos campos antes da serialização. Por exemplo, visto que “HandField” utiliza strings para armazenar dados, nós podemos reutilizar algum código de conversão existente:

```
class HandField(models.Field):
    # ...

    def value_to_string(self, obj):
        value = self.value_from_object(obj)
        return self.get_prep_value(value)
```

### Alguns avisos gerais

Escrever um um campo personalizado pode ser um um pouco complicado, particularmente se estiver fazendo conversões complexas entre tipos Python e o banco de dados e formatos de serialização. Aqui algumas dicas par fazer as coisas mais tranquilas.

1. Look at the existing Django fields (in
   [django/db/models/fields/\_\_init\_\_.py](https://github.com/django/django/blob/stable/4.2.x/django/db/models/fields/__init__.py)) for inspiration. Try to find
   a field that’s similar to what you want and extend it a little bit,
   instead of creating an entirely new field from scratch.
2. Coloque o método `__str__()` na classe que você está utilizando para envelopar o campo. Em vários lugares o comportamento padrão do código do campo é chamar `str()`. (Em nossos exemplos neste documento, `value` seria uma instância de `Hand` e não de `HandField`). Então se o método `__str__()` da sua classe converter o objeto para o formato de texto, você poderá poupar bastante trabalho.

## Escrevendo uma subclasse  `FileField`

Além dos métodos acima, campos que lidam com arquivos tem alguns outros requerimentos especiais que devem ser levados em conta. A maioria dos mecanismos fornecidos pelo FileField\`, como controlar o armazenamento e leitura na base de dados, podem permanecer inalterados, deixando as subclasses lidarem com o desafio de dar suporte a um tipo de arquivo particular.

O Django fornece uma classe `File`, a qual é usada como um proxy para conteúdos e operações de arquivos . Isso pode ser herdado para customizar como o arquivo é acessado, e quais métodos estão disponíveis. Isso está em `django.db.models.fields.files`, e seu comportamento padrão é explicado no [arquivo documentação](/pt-br/4.2/ref/files/file/).

Once a subclass of `File` is created, the new `FileField` subclass must be
told to use it. To do so, assign the new `File` subclass to the special
`attr_class` attribute of the `FileField` subclass.

### Algumas sugestões

Além dos detalhes acima, tem algumas orientações as quais podem melhorar muito a eficiência e a legibilidade do código do campo.

1. The source for Django’s own `ImageField` (in
   [django/db/models/fields/files.py](https://github.com/django/django/blob/stable/4.2.x/django/db/models/fields/files.py)) is a great example of how to
   subclass `FileField` to support a particular type of file, as it
   incorporates all of the techniques described above.
2. Faça o cache dos atributos do arquivo sempre que possível. Uma vez que é possível que arquivos sejam armazenados em sistemas de armazenamento remotos, recuperá-los talvez requeira tempo extra, ou mesmo dinheiro, que não é sempre necessário. Uma vez que o arquivo é recuperado para obter alguns dados sobre seu conteúdo, faça o cache de dados o quanto possível para reduzir o número de vezes que o arquivo deve ser recuperado em chamadas subsequentes para aquela informação.
