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>