DJango – ModelChoiceField – MySQL – Python

Publicado: 24 de fevereiro de 2015 em Python

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:

Django - SyncDB

Django – SyncDB

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:

MySQL - Relacionamento - Chave Estrangeira

MySQL – Relacionamento – Chave Estrangeira

3 – Utilize os códigos abaixo e rode sua aplicação:

DJango - Aplicação

DJango – 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:

MySQL - WorkBench

MySQL – WorkBench

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>

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s