Na maioria das vezes é útil utilizar componentes de listas conhecidos como Combobox ou Dropdown para mostrar relacionamentos de dados entre tabelas e de uma forma amigável exibir a descrição dos itens de dados e manipular seu identificador único. Para isto o DJango nos disponibiliza componentes e classes no qual nos permite manipular dados através de objetos e persisti-los em um banco de dados relacional usando o DJango ORM. Um relacionamento de dados mais simples é criado através de duas tabelas, sendo uma tabela pai que contem os dados mestres e uma filho que contem um ou mais identificadores relacionados ao pai. Um modo de fácil de identificar e tradicional de utilizar relacionamentos em um banco de dados é através de chaves estrangeiras, uma chave estrangeira é um campo, que aponta para a chave primária de outra tabela ou da mesma tabela. Ou seja, passa a existir uma relação entre duas tabelas ou de uma única tabela. A finalidade da chave estrangeira é garantir a integridade dos dados referenciais, pois apenas serão permitidos valores que supostamente vão aparecer na base de dados e estão ligados ao registro mestre.
O DJango possui o elemento ModelChoiceField que nos possibilita retornar dados diretamente do modelo, permitindo a seleção de um único objeto do modelo, adequado para a representação de uma chave estrangeira, possibilita ainda um numero de possíveis diferentes configurações.
ModelChoiceField: https://docs.djangoproject.com/en/dev/ref/forms/fields/#modelchoicefield
Exibindo Relacionamentos
1 – Após criar um novo projeto e uma aplicação Django e o configure adequadamente para acessar o banco de dados MySQL, utilize o modelo disponibilizado no código abaixo e sincronize o banco de dados:
2 – O Modelo criou duas tabelas e seus respectivos objetos no banco de dados MySQL , atente-se para a chave estrangeira que cria o relacionamento entre as tabelas usando a chave primaria da tabela pai:
3 – Utilize os códigos abaixo e rode sua aplicação:
4 – Assim que os dados forem enviados o DJango ORM gravará o conteúdo dos objetos no banco de dados relacional, você pode verificar na pagina que mostramos a descrição do campo cargo toda vez que utilizamos os dados da tabela de Cargos, porem na tabela Funcionário apenas seu identificador é gravado formando o relacionamento entre as duas tabelas:
Exemplo:
Neste exemplo criamos duas tabelas no banco de dados MySQL e as relacionamos através da chave primaria e uma chave estrangeira. Usamos um elemento DJango para tornar este relacionamento amigável, exibindo assim a descrição do relacionamento mas manipulando seu identificador e os persistindo através do DJango ORM.
Python
Model
from django.db import models
# Cria modelo Funcionario
class Funcionario (models.Model):
nome = models.CharField(max_length=30)
sobrenome = models.CharField(max_length=50)
id_cargo = models.ForeignKey('Cargo')
data = models.DateField()
salario = models.DecimalField(max_digits=19, decimal_places=10)
genero = models.CharField(max_length=30)
ativo = models.BooleanField()
observacao = models.CharField(max_length=255)
# Define unicode para o Django Admin
def __unicode__(self):
return u'{0}'.format(self.nome)
# Cria modelo Cargo
class Cargo (models.Model):
nome = models.CharField(max_length=50)
def __unicode__(self):
return u'{0}'.format(self.nome)
View
from django.shortcuts import render, render_to_response, RequestContext
from django.http import HttpResponse
# Importa form
from meusite.forms import MeuForm
# Exibe View
def home(request):
# Cria form
form = MeuForm(request.POST or None)
# Valida e salva
if form.is_valid():
salvar = form.save(commit=False)
salvar.save()
return HttpResponse("Dados inseridos com sucesso!")
# Chama Template
return render_to_response("devaberto.html",
locals(),
context_instance = RequestContext(request))
Forms
from django import forms
from django.forms import extras
from django.core.validators import RegexValidator
# Importa modulo Regex
import re
# cria objeto Regex
caracteres = RegexValidator(
# regex= re.compile(r"[a-zA-Z]+"),
regex=r"[a-zA-Z]+",
message="Permitido somente caracteres Alpha numericos",
code="invalid")
# Importa modelo
from models import Funcionario
from models import Cargo
# Cria classe do form para o modelo
class MeuForm(forms.ModelForm):
# Cria Conteudo
GENEROS = (("Masculino", "Masculino"), ("Feminino", "Feminino"))
# Define Widgets
nome = forms.CharField(required=True, validators=[caracteres])
sobrenome = forms.CharField(required=True, validators=[caracteres])
id_cargo = forms.ModelChoiceField (queryset=Cargo.objects.all().order_by('id'), widget=forms.Select)
data = forms.DateField(required=True, widget=forms.extras.SelectDateWidget)
salario = forms.DecimalField()
genero = forms.ChoiceField (required=True, widget=forms.RadioSelect, choices=GENEROS)
ativo = forms.BooleanField()
observacao = forms.CharField(widget=forms.Textarea)
# Associa formulario ao modelo
class Meta:
model = Funcionario
# Django Validations - customizado campo sobrenome
def clean_sobrenome(self):
snome = self.cleaned_data['sobrenome']
if len(snome) <= 3:
raise forms.ValidationError("Sobrenome precisa conter mais de 3 caracteres.")
return snome
Template
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Desenvolvimento Aberto</title>
<style>
body {
font-family: "Times New Roman", Times, serif;
font-size: 12px;
}
</style>
</head>
<body>
<h1>Desenvolvimento Aberto - Django - Elementos - Widgets </h1>
<form method="post" action="">
<fieldset>
<legend>
Cadastro:
</legend>
{% csrf_token %}
<table>
<td> {{ form.as_table }} </td>
</table>
<hr />
<input type="submit" />
</fieldset>
</form>
</body>
</html>





