Como herdar Classes de Modelo
A herança entre classes de modelo pode ser muito útil, especialmente para duas coisas:
- manter uma referência única para um conjunto de funcionalidades compartilhadas por mais de uma classe de modelo;
- gravar informações similares em uma estrutura hierárquica sem aumentar a complexidade.
O Django trabalha com herança de classes de modelo de duas formas diferentes:
- Herança de classe abstrata - uma classe abstrata não possui tabela no banco de dados, portanto, as classes que herdam dela criam seus campos na própria tabela;
- Herança de classe não-abstrata - a classe herdada possui sua própria tabela, com os dados centralizados ali, e as classes extendidas criam apenas seus próprios campos e uma referência ao registro da tabela da classe herdada.
Herança de Classes Abstratas
Vamos supor que você possua uma aplicação chamada "pessoas", que possui duas classes: Cliente e Funcionario, que compartilham alguns campos, comuns de pessoas, como nome, data_nascimento e endereco. Nesse caso, ter uma classe abstrata, que centralize os campos referentes a uma pessoa, pode ser bastante útil para você compartilhar funcionalidades referentes a esses campos e manter a coesão dos dados. Entretanto, os campos existirão tanto na tabela de clientes, quanto na de funcionários.
Para fazer a estrutura citada acima, escreva o código abaixo no arquivo models.py da aplicação:
from django.db import models class Pessoa(models.Model): class Meta: abstract = True nome = models.CharField(max_length=100) data_nascimento = models.DateField() endereco = models.CharField(max_length=100) class Cliente(Pessoa): compra_sempre = models.BooleanField(default=False) class Funcionario(Pessoa): ctps = models.CharField(max_length=25) salario = models.DecimalField(max_digits=15, decimal_places=2)
Agora, ao rodar o comando para criar as tabelas, veja que somente as tabelas de Cliente e Funcionario são criadas:
$ python manage.py syncdb Creating table pessoas_cliente Creating table pessoas_funcionario
Herança de Classes Não-Abstratas
Supondo agora que essa mesma aplicação possua uma classe chamada LigacaoTelefonica, que pode ser classificada de duas formas: LigacaoTelefonicaComum e LigacaoTelefonicaACobrar. Você quer ter o poder de resgatar listagens de ligações telefônicas de um tipo específico ou de ambos.
Este é o caso para uma herança de classe não-abstrata. Pois a classe LigacaoTelefonica continuará existindo com todos os atributos e funcionalidades de uma classe persistente comum. E o resultado final serão 3 tabelas, uma para cada classe.
Para isso, escreva o código abaixo no arquivo models.py de sua aplicação:
from django.db import models class LigacaoTelefonica(models.Model): numero_origem = models.CharField(max_length=25) numero_destino = models.CharField(max_length=25) data_hora = models.DateTimeField() class LigacaoTelefonicaComum(LigacaoTelefonica): operadora = models.PositiveIntegerField() class LigacaoTelefonicaACobrar(LigacaoTelefonica): motivo = models.CharField(max_length=100)
Agora veja o resultado final, ao criar as tabelas:
$ python manage.py syncdb Creating table pessoas_ligacaotelefonica Creating table pessoas_ligacaotelefonicacomum Creating table pessoas_ligacaotelefonicaacobrar
Note que foram criadas as 3 tabelas.
Tire outras dúvidas em nosso CookBook em Português