python manage.py startapp cd
Este comando irá criar uma pasta com 3 arquivos:
- __init__.py
- models.py
Neste arquivo será colocado todos os modelos da aplicaçã - views.py
Aqui ficam as views que utilizaremos no front. Voltaremos a falar delas mais a frente.
Por hora abra o models.py.
Acima da importação do pacote models, coloque a codificação a ser utilizada:
# -*- coding: utf-8 -*-
from django.db import models
Deixando tudo em UTF-8, problemas de acentuação tanto no banco quanto nos templates serão evitados.
Mantenha essa string sempre na primeira linha de todos os models.py e views.py.
CRIANDO O PRIMEIRO MODELO
Nesta aplicação, defini que os cds serão divididos por categoria, intérprete e conterão algumas informações espefíficas do album tais como: foto, ano e faixas. Vamos ao código:
A classe categoria:
class Categoria(models.Model):
nome = models.CharField(max_length=100)
slug = models.SlugField(max_length=100)
class Meta:
ordering = ['nome']
def __unicode__(self):
return self.nome
A classe categoria herda as propriedades da classe Model, por isso o import nas primeiras linhas.
Os atributos:
nome = models.CharField(max_length=100)
slug = models.SlugField(max_length=100)
Ambos serão renderizados como um INPUT TEXT no admin, porém o campo slug gera uma melhor indexação no banco, além de ser o grande responsável pelas urls elegantes que criaremos para as views.
Em ambos os casos o parâmetro max_length é obrigatório.
O campo slug será utlizado de forma a identificar um registro nos banco de forma única no banco, e será preenchido de uma forma interessante quando chegarmos na administração desse modelo.
A classe Meta, que está definida dentro de da classe recém criada possui muitos recursos interessantes. Para categoria, estou utilizando apenas a ordenação padrão quando os objetos da mesma forem listados:
ordering = ['nome']
Com o ordering posso colocar a ordenação por quaisquer atributos pertencentes a minha classe, e utilizar o sinal "-" (menos) para ordenação decrescente, como por exemplo:
ordering = ['-id']
O método __unicode__ é o responsável por retornar uma string contendo o conteudo de qualquer campo da instância do objeto em questão. Caso ele não esteja defindo, ocorre a seguinte diferença para um objeto c pertencente a esta classe:
c - retornaria: OBJECT
c.nome - retornaria o valor do atributo nome
Já com o __unicode__, ambos os casos retornariam diretamente o valor, o que poupa trabalho.
A classe Interprete:
class Interprete(models.Model):
nome = models.CharField(max_length=100)
slug = models.SlugField(max_length=100)
def __unicode__(self):
return self.nome
class Meta:
ordering = ['-id']
verbose_name = u'Intérprete'
verbose_name_plural = u'Intérpretes'
Aqui temos dois novos recursos da classe meta. É possivel setar qual será o nome no singular e no plural através do verbose_name, de forma a deixar correto (com acento) no admin.
A classe Album:
class Album(models.Model):
categoria = models.ForeignKey(Categoria)
interprete = models.ForeignKey(Interprete)
titulo = models.CharField(max_length=255,verbose_name=u'Título')
cover = models.ImageField(upload_to='albuns/%Y/', null=True, blank=True)
ano = models.IntegerField()
slug = models.SlugField(max_length=255)
def __unicode__(self):
return self.titulo
class Meta:
ordering = ['-id']
verbose_name = u'Album'
verbose_name_plural = u'Albuns'
Aqui temos algumas novidades em relação as anteriores:
- É possivel utilizar o verbose_name para atributos de forma a corrigir o nome mostrado no admin, conforme visto no título;
- Para nomes com acentos, se faz necessário colocar a letra "u" antes da string com o mesmo, para ficar correto com a codificação;
- um campo do tipo Imagem para fazer o upload da capa do álbum. O parâmetro upload_to é obrigatório e deve ser a string do caminho onde ficarão as imagens. Também é possivel organizar os uploads por datas. Neste exemplo, será gerada a pasta albuns dentro do media, e dentro dela, uma pasta com o ano que fez o upload defindo pelo caracter "%Y". Observação: o ano do álbum não está relacionado com o caminho do upload;
- Para o campo cover, temos dois parâmetros opcionais que permitem ao usuário criar um álbum sem a necessidade de preencher este campo. Colocando ambos campos em um atributo, o django exclui o mesmo da validação automática.
- Temos duas chaves estrangeiras para a classe album: categoria e interprete. Previmente definidos;
- E por fim, o campo do tipo inteiro ano, que também será renderizado como um INPUT TEXT no admin.
A classe Faixa:
class Faixa(models.Model):
album = models.ForeignKey(Album)
nro = models.IntegerField(verbose_name = u'Número')
nome = models.CharField(max_length=200)
tempo = models.CharField(max_length=10, help_text='Formato MM:SS',blank=True,null=True)
def __unicode__(self):
return self.nome
A novidade na classe faixa é uma dica dada ao usuário sobre o correto preenchimento para um campo na administração. Utilizando o atributo opcional help_text, a mensagem desejada aparece ao lado do campo escolhido.
CRIANDO O ADMIN PARA O MODELO
Crie dentro da pasta da sua aplicação um arquivo com o nome de admin.py. Dentro dele precisaremos de dois imports:
from django.contrib import admin
from app.cd.models import *
O primeiro para as funcionalidades do admin em si, e o segundo para as informações do modelo criado.
Logo abaixo, será criado as classes do administrativo:
O admin de Categoria:
class CategoriaAdmin(admin.ModelAdmin):
search_fields = ('nome',)
list_display = ('nome',)
prepopulated_fields = {'slug': ('nome',)}
save_on_top = True
search_fields - recebe uma tupla com os campos em que será realizada uma busca por quaisquer ocorrências do que for digitado.
list_display - recebe uma tupla com os campos que aparecerão na listagem
prepopulated_fields - aqui um recurso interssante do django para o campo slug. O preenchimento automático do campo slug com o texto do quer for inserido no campo nome, com excessão de algumas palavras reservadas, espaços e acentuação.
save_on_top - útil para formulários grandes. Esta opção replica a barra de controle para salvar/apagar registros acima do form.
O admin de Interprete:
class InterpreteAdmin(admin.ModelAdmin):
search_fields = ('nome',)
list_display = ('nome',)
prepopulated_fields = {'slug': ('nome',)}
save_on_top = True
Vamos utilizar um recurso muito interessante para as duas classes que faltam. Imagine se tivesse que inserir primeiro álbum com todas as informações, depois ir até o administrativo de faixas para inserir uma a uma tendo que escolher o álbum. Trabalhoso demais. O Django possui uma solução para isso.
É possível utilizar um recurso chamado INLINE, para adicionar uma ou várias faixas durante a inserção do álbum. Vejamos como:
O admin inline de Faixa:
class FaixasInline(admin.TabularInline):
model = Faixa
extra = 15
Esta classe herda de uma classe diferente das outras extamente por possuir esse recurso. Apenas precisamos definir a qual modelo ela se refere:
model = Faixa
E a quantidade de itens que serão exibidas além dos preenchidos:
extra = 15
O admin de Album:
class AlbumAdmin(admin.ModelAdmin):
inlines = [
FaixasInline,
]
raw_id_fields = ('categoria','interprete',)
search_fields = ('titulo',)
list_display = ('titulo','interprete','categoria','ano')
list_filter = ['categoria']
prepopulated_fields = {'slug': ('titulo',)}
save_on_top = True
Novidades desta classe:
- Nesta classe, é definido que será utilizado a classe FaixasInline criada anteriormente
- Como provavelmente teremos muitos artistas e categorias, procurá-los em um campo do tipo SELECT (tipo renderizado pelos campos ForeignKey) seria um tanto trabalhoso. Com a opção raw_id_fields, é aberto uma nova janela com a listagem definida pela referência a chave estrangeira, de forma a utilizar todas as buscas, filtros e ordenação providas pelo admin da mesma.
- list_filter - gera um filtro para facilitar a busca de um registro. O filtro só é exibido quando esta classe possuir registros pertencentes a mais de uma classe do filtro.
O admin de Faixa:
class FaixaAdmin(admin.ModelAdmin):
search_fields = ('nome',)
list_display = ('nome','album','nro','tempo')
save_on_top = True
Para concluir o admin.py, registre os admins criados ao final do arquivo:
admin.site.register(Categoria, CategoriaAdmin)
admin.site.register(Interprete, InterpreteAdmin)
admin.site.register(Album, AlbumAdmin)
admin.site.register(Faixa, FaixaAdmin)
TESTES
Adicone dentro do INSTALLED_APPS no settings.py a aplicação criada.
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.admin',
'app.cd',
)
Pare o servidor local de testes caso esteja rodando e execute um syncdb para gerar as tabelas.
Inicie novamente o servidor de testes com o runserver e abra o admin do seu projeto no link:
http://localhost:8000/admin/
Faça o login e veja o foi criado.
Nenhum comentário:
Postar um comentário