Mostrando postagens com marcador tutorial. Mostrar todas as postagens
Mostrando postagens com marcador tutorial. Mostrar todas as postagens

quarta-feira, 3 de setembro de 2014

Django 1.7 - Getting Started!

Saiu a versão tão esperada do Django, a 1.7.

Algumas novidades importantes antes de começarmos:

  • Suporte ao python 3.3.
  • Retirou o suporte ao python 2.6.
  • Sistema de migração de banco nativo ( integração com South ).

Vou tentar registrar aqui o que tive que fazer para iniciar um projeto e conforme for surgindo as novidades vou atualizando o post.


Como instalar uma nova versão do Python:



Bom pra começar, eu tinha o python 2.6 e por isso precisei atualizar. 

O ambiente que utilizo é windows 7 e uso uma máquina virtual com o Vagrant para rodar os projetos. Para futuras referencias abaixo, tudo será feito dentro do terminal do vagrant. Para mais informações: 

Para este início, vou instalar a versão 2.7.8 do python. Para isso faça o download em algum lugar do source e instale com os comandos abaixo:
wget https://www.python.org/ftp/python/2.7.8/Python-2.7.8.tgz
tar -xvf Python-2.7.8.tgz
cd Python-2.7.8/
./configure
make
sudo make install

Caso não tenha o make instalado, era o meu caso, utilize o comando abaixo e posteriormente a instalação conclua os passos acima.
sudo apt-get install make


Como criar o virtualenv com o python recém instalado:



Para criar o ENVo comando é o mesmo visto nos links acima:
virtualenv --no-site-packages --unzip-setuptools django17 --python=/usr/local/bin/python2.7

Aqui tive outro problema: A versão do virtualenv que tinha, não era compativel com o python 2.7. Portanto tive que atualizar  o virtualenv também:
sudo pip install virtualenv --upgrade

Depois de instalado, o comando ficou:
virtualenv-2.6 --no-site-packages --unzip-setuptools django17 --python=/usr/local/bin/python2.7

No comando acima vale prestar atenção na versão do virtualenv chamado e no parâmetro python passado ao sistema indicar o caminho do python desejado.

Com o ENV chamado django17 criado, vamos agora instalar as dependências que nosso projeto precisa, primeiramente ligue o env:
. django17/bin/activate

E instale o que desejar usando o pip, como por exemplo:
pip install django
pip install MySQL-python
pip install sorl-thumbnail==11.12.1b

A versão da sorl.thumbnail foi especificada pois a final ainda não tem compatibilidade com o Django 1.7, por isso instalei a beta.




Ajustando o settings para rodar o projeto



Achei que o settings.py nativo veio bem mais enxuto, e por hora mudarei apenas duas configurações:
LANGUAGE_CODE = 'pt-br'
TIME_ZONE = 'America/Sao_Paulo'

E no fim do arquivo adicionarei a importação das configurações que farei a sobreposição para rodar o projeto local:
try:
 from local_settings import *
except:
 pass


Criei um arquivo chamado local_settings.py no mesmo diretório do settings.py com as seguintes configurações:
# coding: utf-8
SITE_URL = 'http://localhost:8000'
DATABASES = {
 'default': {
  'ENGINE': 'django.db.backends.mysql', 
  'NAME': 'django17',        
  'USER': 'root',    
  'PASSWORD': '',    
  'HOST': '',    
  'PORT': '',    
 }
}

DEBUG = True
LOCAL = True
USE_TZ = False

if not DEBUG:
 ALLOWED_HOSTS = ['localhost',]

Ajuste neste arquivo as configurações necessárias, como DEBUG, acesso ao banco, etc.

Não se esqueça de criar uma database com o nome especificado a seu gosto no SGBD de sua preferência.


Criação das tabelas:



Para criação das tabelas padrões do django, utilize o comando abaixo. Ele será usado sempre que for instalar uma aplicação, tendo esta migrações ou não.
./manage.py migrate




Criar o super usuário do Admin:



Agora nesta versão,  o migrate (antigo syncdb) não cria mais um super usuário para o administrativo. Você deve fazer isso manualmente com o comando:
./manage.py createsuperuser

E preencha conm seu usuário, email e senha, da mesma forma que era feito antes.


Como realizar migrações dos models com makemigrations / migrate



Pra quem já utilizava o South , não terá muita dificuldade em mudar para o sistema de migração nativo que a versão 1.7 ofecere.

Para uma nova aplicação ou qualquer mudança feita no models de uma aplicação o procedimento é o mesmo:
./manage.py makemigrations debug


E depois rode novamente o migrate, passando ou não sua app:
./manage.py migrate debug




Para rodar o projeto:



Para rodar o projeto execute o comando abaixo. Ele rodará servidor e porta padrão do ambiente desenvolvimento: localhost:8000. Para mudar o servidor e/ou porta basta especificar o desejado a frente do parâmetro.
./manage.py runserver




Novidades do admin:



  • Agora é possivel alterar algumas configurações do admin sem ter que sobrepor templates. Em qualquer arquivo admin.py dentro da sua aplicação utilize o código abaixo:
# coding: utf-8

from django.contrib import admin

admin.site.site_header = u"Administração do Site"
admin.site.index_title = u"Administração do Site"
admin.site.site_title = u"Site de Administração do Django"



  • Agora os botões com cantos arredondados utilizam a propriedade border-radius do CSS ao invés de GIFs.
  • No changelist, agora as células tem uma classe CSS chamada field-<field_name> para facilitar customizações.
  • Além da sintaxe admin.site.register existente , você pode usar o decorador novo register() para registrar um ModelAdmin.
  • Agora é possível  especificar ModelAdmin.list_display_links = None desativar links na grade página de listagem.

Chamar métodos customizados do Queryset pelo Manager


class FoodQuerySet(models.QuerySet):
    def pizzas(self):
        return self.filter(kind='pizza')

    def vegetarian(self):
        return self.filter(vegetarian=True)

class Food(models.Model):
    kind = models.CharField(max_length=50)
    vegetarian = models.BooleanField(default=False)
    objects = FoodQuerySet.as_manager()

Food.objects.pizzas().vegetarian()


Veja estas e outras dicas interessantes sobre tudo que mudou para esta versão no link oficial:
https://docs.djangoproject.com/en/1.7/releases/1.7/

hasta!

quarta-feira, 7 de maio de 2014

Paginação estilo Twitter com Django CBV e django-endless-pagination



Quem já não precisou fazer uma paginação ao estilo do twitter? Bom não é complicado. Pelo menos não com as dicas abaixo!

Requisitos necessários:

  • Python >= 2.6
  • Django >= 1.3
  • jQuery >= 1.7


Instalação:
pip install django-endless-pagination

Configuração:


Adicione a app na setting INSTALLED_APPS no settings.py:
...
'endless_pagination',
...

Adicione a linha abaixo na setting TEMPLATE_CONTEXT_PROCESSORS também no settings.py:
...
'django.core.context_processors.request',
...

Na views.py

from django.shortcuts import render, render_to_response, get_object_or_404
from django.template import Context, loader, RequestContext
from .models import Produto

class ProdutoTTPag(View):
 def get(self, request, *args, **kwargs):

  template = 'produtos/lista-produtos.html'
  page_template = 'produtos/paginacao.html'

  produtos = Produto.objects.filter(ativo=True)
  
  context = {
   'page_template': page_template,
   'produtos_list' : produtos,
  }

  if request.is_ajax():
   template = page_template

  return render_to_response(template, context, context_instance=RequestContext(request))


No urls.py

Adicione a linha abaixo:
...
url(r'^(?P[-\w]+)/$', views.ProdutoTTPag.as_view(), name='produtos'),
...


No template:

Aqui será necessário a criação de dois arquivos html. Um para ser de fato a lista (lista-produtos.html) e o outro para ser apenas os itens, para que o ajax possa trazê-los de forma correta (paginacao.html).

lista-produtos.html:
...
{% load endless %}
...

{% block extra_js %}
    <script src="{{ STATIC_URL }}endless_pagination/js/endless-pagination.js" type="text/javascript"></script>
    <script type="text/javascript">
     jQuery(document).ready(function($) {
      //$.endlessPaginate({
         //    paginateOnScroll: true,
         //    paginateOnScrollChunkSize: 5,
         //    paginateOnScrollMargin: 200
         //});

      $.endlessPaginate({});
     });
    </script>
{% endblock extra_js %}

...
<section class="list-products">
 <ul>
  {% include page_template %}
 </ul>
...
</section>

Aqui a parte comentada serve para trazer os resultados das outras páginas conforme o scroll da página.

paginacao.html:

{% load endless %}

{% paginate 9 produtos_list %}
{% for p in produtos_list %}
 <li>
  {# HTML PARA ITEM DO PRODUTO #}
 </li>
{% endfor %}
{% show_more %}

Mais informações em:

  1. http://django-endless-pagination.readthedocs.org/en/latest/index.html
  2. https://github.com/frankban/django-endless-pagination
  3. https://pypi.python.org/pypi/django-endless-pagination/2.0


hasta!

sexta-feira, 23 de agosto de 2013

Como utilizar os inlines no front para os ModelForms (class based view)

Assim como prometido, mesmo que com uma "pequena" demora, segue a continuação do post
Como utilizar os inlines no front para os ModelForms (function based view). Faremos algo bem similar com alguns detalhes a mais.

Objetivo é fornecer um formulário de cadastro e este pode fazer uploads de fotos. Quando o email já existir no banco de dados, faremos que as fotos do segundo envio seja direcionadas para o primeiro cadastro, do contrário, uma nova instancia para todos os objetos envolvidos.

models.py

from django.db import models

# Create your models here.

class Cadastro(models.Model):
 """(Cadastro description)"""
 nome = models.CharField(max_length=255)
 email = models.EmailField(verbose_name='E-mail')
 telefone = models.CharField(max_length=20)
 aceite = models.BooleanField(default=True)
 data = models.DateField(auto_now_add=True)
 hora = models.TimeField(auto_now_add=True)

 class Meta:
  verbose_name, verbose_name_plural = u"Cadastro" , u"Cadastros"
  ordering = ('-data',)

 def __unicode__(self):
  return "%s" % self.nome

class Foto(models.Model):
 """(Foto description)"""
 cadastro = models.ForeignKey(Cadastro)
 foto = models.ImageField(upload_to="uploads/fotos/foto/%Y")
 data = models.DateField(auto_now_add=True)
 hora = models.TimeField(auto_now_add=True)
 aprovado = models.BooleanField(default=False)

 class Meta:
  verbose_name, verbose_name_plural = u"Foto" , u"Fotos"
  ordering = ('-data',)

 def __unicode__(self):
  return "%s" % self.id

 def thumb_admin(self):
  from sorl.thumbnail import get_thumbnail
  im = get_thumbnail(self.foto, '120x120', crop='center', quality=99)
  if im:
   return  '<a href="http://www.blogger.com/media/%s" onclick="window.open(this.href);return false;"><img alt="Imagem" src="%s" /></a>' % (self.foto, str(im.url))
  return  'Sem foto'
 thumb_admin.is_safe = True
 thumb_admin.allow_tags = True
 thumb_admin.short_description = 'Thumb'

admin.py

from django import forms
from django.contrib import admin
from .models import *

class FotoInline(admin.TabularInline):
 model = Foto
 readonly_fields = ['foto',]
 extra = 5


class CadastroAdmin(admin.ModelAdmin):
 inlines = [
  FotoInline,
 ]
 search_fields = ('nome', 'email',)
 list_display = ('nome', 'email','telefone','data', 'hora',)
 list_filter = ['data',]
 date_hierarchy = 'data'
 readonly_fields = ['nome', 'email','telefone','aceite']
 save_on_top = True

admin.site.register(Cadastro, CadastroAdmin)



class FotoAdmin(admin.ModelAdmin):
 
 list_display = ('cadastro', 'data', 'hora','thumb_admin','aprovado')
 list_filter = ['data','aprovado']
 date_hierarchy = 'data'
 list_editable = ['aprovado']
 readonly_fields = ['cadastro','foto',]
 save_on_top = True

admin.site.register(Foto, FotoAdmin)

forms.py

# coding: utf-8
from django import forms
from django.utils.translation import ugettext_lazy as _
from .models import *
from util import util as U

from django.forms.models import inlineformset_factory

class CadastroForm(forms.ModelForm):
 class Meta:
  model = Cadastro


class FotoForm(forms.ModelForm):

 aprovado = forms.BooleanField(initial=False, required=False)
 aceite = forms.BooleanField(initial=True)

 class Meta:
  model = Foto


 def dados(self):
  return {'form':self.cleaned_data, 'data':datetime.now()}

 def clean(self):
  cleaned_data = super(FotoForm, self).clean()
  #if cleaned_data.get("senha") != cleaned_data.get("confirme"):
  # self._errors["confirme"] = self.error_class(['Senha nao confere'])
  return self.cleaned_data


FotoFormSet = inlineformset_factory(Cadastro, Foto, extra=5)

urls.py

# coding: utf-8
from django.conf.urls.defaults import patterns, include, url

from . import views

urlpatterns = patterns('fotos.views',
 url(r'^$', views.CadastroView.as_view(), name='cadastro_form'),
)

form.html

<html>
 <head>
 <meta charset="utf-8">
 <title></title>
 </head>
 <body>
  <form action="" method="post" enctype="multipart/form-data">
   {% csrf_token %}
   {{ form.errors }}

   <p>Nome:{{ form.nome }}</p>
   <p>Telefone: {{ form.telefone }}</p>
   <p>E-mail: {{ form.email }}</p>
   <p>Foto: {{ form.foto }}</p>
   <p>Aceite: {{ form.aceite }}</p>

   {{ foto_formset.management_form }}
   {% for form in foto_formset %}
    {{ form.id }}
    <div class="form-row inline {{ foto_formset.prefix }}">
     {{ form.foto.label_tag }}
     {{ form.foto }}
     {{ form.foto.errors }}
    </div>
   {% endfor %}

   <input type="submit" name="" value="Enviar">

  </form>
 </body>
</html>

views.py

class CadastroView(CreateView):
 #template_name = 'form.html'
 template_name = 'index.html'
 model = Cadastro
 form_class = CadastroForm
 success_url = '/envie/?sucesso=1#sucesso'

 def form_valid(self, form):
  context = self.get_context_data()
  foto_form = context['foto_formset']

  email = form.cleaned_data['email']

  if foto_form.is_valid():
   print "erros: %s" % foto_form.errors
   if Cadastro.objects.filter(email=email):
    foto_form.instance = Cadastro.objects.get(email=email)
   else:
    self.object = form.save()
    foto_form.instance = self.object
   foto_form.save()
   return HttpResponseRedirect('/envie/?sucesso=1#sucesso')
  else:
   addDebug("erros: %s" % foto_form.errors)
   return self.render_to_response(self.get_context_data(form=form))

 def form_invalid(self, form):
  return self.render_to_response(self.get_context_data(form=form))

 def get_context_data(self, **kwargs):
  context = super(CadastroView, self).get_context_data(**kwargs)
  r = self.request.POST
  f = self.request.FILES  

  if r and f:
   context['foto_formset'] = FotoFormSet(self.request.POST,f)
  else:
   context['foto_formset'] = FotoFormSet()
  return context

cadastro.js

jQuery(document).ready(function($) {

 $('.bt-mais').click(function(event) {
  if($('.enviar-foto-fake').length < 5){
   $('.enviar-foto-fake').last().clone().insertAfter($('.enviar-foto-fake').last());
   $('.enviar-foto-fake').last().find('div p.nome-foto').text('Você pode enviar até cinco fotos');
   $('.enviar-foto-fake').last().find('input').attr({
    id: 'id_foto_set-'+($('.enviar-foto-fake').length-1)+'-foto',
    name: 'foto_set-'+($('.enviar-foto-fake').length-1)+'-foto'
   });
   $('#id_foto_set-TOTAL_FORMS').val($('.enviar-foto-fake').length);
  }

  if ($('.enviar-foto-fake').length == 5) {
   $(this).hide();
  };

 })
});

hasta!

sexta-feira, 10 de fevereiro de 2012

Instalação do Vagrant no windows


Precisa de um ambiente que simule o servidor onde fará o deploy do projeto? Cansado de lidar com as diferenças entre sistemas operacionais, versões etc?

Esta semana tive a oportunidade de conhecer o Vagrant. Um sistema que trabalha com a API do Virtual Box. Nele é possível de uma maneira fácil criar uma máquina virtual com as características que precisar para simular o ambiente online.

O tutorial abaixo mostra um resumo do que li a respeito para  criar uma VM com Ubuntu, python2.6, virtualenv, etc.

  1. Baixe e instale a Oracle VM Virtual Box (https://www.virtualbox.org/wiki/Downloads) 
  2. Baixe e instale o Ruby (http://rubyinstaller.org/downloads/) 
  3. Baixe o Development Kit (http://rubyinstaller.org/downloads/) 
    1. Installation Instructions (https://github.com/oneclick/rubyinstaller/wiki/Development-Kit) 
      1. While installation is (in general) simple, please ensure you carefully follow each step below. 
      2. Preparation 
      3. If you previously installed the legacy DevKit devkit-3.4.5r3-20091110.7z, its artifacts were extracted into each Ruby installation and need to be manually removed. Remove the gcc.bat, make.bat, and sh.bat stub batch files in <RUBY_INSTALL_DIR>\bin and the <RUBY_INSTALL_DIR>\devkit subdirectory for each Ruby installation using the legacy DevKit. 
      4. If you previously installed one of the legacy self-extracting DevKit’s, follow the SFX DevKit upgrade instructions. 
    2. Download Files 
      1. The current DevKit is available at the RubyInstaller download page with older versions available at the archives page. As backup, check our GitHub downloads page. 
    3. Extract Files 
      1. Left double-click the self-extracting executable (SFX) downloaded from Step 2 and choose a directory (without spaces) to install the DevKit artifacts into. For example, C:\DevKit. NOTE: the SFX is really a 7-Zip archive with a bit of embedded magic. If you already have 7-Zip installed, you can simply right-click it and extract it’s contents as you would a normal 7z archive. In the instructions that follow, the directory that you selected is identified as <DEVKIT_INSTALL_DIR>. 
    4. Run Installation Scripts 
      1. cd <DEVKIT_INSTALL_DIR> from Step 3 above. 
      2. ruby dk.rb init to generate the config.yml file to be used later in this Step. Your installed Rubies will be listed there (only those installed by a RubyInstaller package are detected at present). 
      3. edit the generated config.yml file to include installed Rubies not automagically discovered or remove Rubies you do not want to use the DevKit with. 
      4. [optional] ruby dk.rb review to review the list of Rubies to be enhanced to use the DevKit and verify the changes you made to it are correct. 
      5. finally, ruby dk.rb install to DevKit enhance your installed Rubies. This step installs (or updates) an operating_system.rb file into the relevant directory needed to implement a RubyGems pre_install hook and a devkit.rb helper library file into <RUBY_INSTALL_DIR>\lib\ruby\site_ruby. NOTE: you may need to use the --force option to update (with backup of the originals) the above mentioned files as discussed at the SFX DevKit upgrade FAQ entry. 
    5. Test Installation 
  4. Confirm your Ruby environment is correctly using the DevKit by running gem install rdiscount --platform=ruby. RDiscount should install correctly and you should see Temporarily enhancing PATH to include DevKit... in the screen messages. Next run ruby -rubygems -e "require 'rdiscount'; puts RDiscount.new('**Hello RubyInstaller**').to_html" to confirm that the rdiscount gem is working. 
  5. Adicione o caminho da pasta bin do ruby da instalção feita no Path. Ex. C:\Ruby193\bin 
  6. Execute o comando: gem install vagrant 
  7. Antes de criar sua maquina, crie uma pasta para abrigar os arquivos de configuraçao: 
    1. mkdir vagrant-machine 
    2. cd vagrant-machine 
    3. vagrant box add lucid32 http://files.vagrantup.com/lucid32.box
    4. vagrant init lucid32 
    5. vagrant up 
    6. Acesse via ssh a maquina virtual: 
    7. pelo putty, conecte em vagrant@127.0.0.1 na porta 2222, com a senha vagrant 
  8. Instale os pacotes de desenvolvimento: 
    1. sudo apt-get install python2.6 python2.6-dev libxml2-dev libxslt1-dev python-libxml2 python-setuptools git-core build-essential libxml2-dev libpcre3-dev libpcrecpp0 libssl-dev zlib1g-dev libgeoip-dev memcached libmemcached-dev python-mysqldb libmysqlclient16-dev python-virtualenv 
    2. Se por ventura der algo errado, tente o mesmo comando acima mas adicione no fim o --fix-missing
  9. É necessário a instalação de alguns pacotes para tudo funcionar perfeitamente, além dos acima. Execute os comandos abaixo, caso não instalar como comando acima:
    1. sudo apt-get update
    2. sudo apt-get install mysql-client
    3. sudo apt-get install libmysqlclient16-dev
    4. sudo apt-get install python-virtualenv
    5. sudo apt-get build-dep python-imaging
  10. Vá até a home do usuário e rode o comando abaixo para atualizar o apt-get e outros pacotes: 
    1. sudo sh postinstall.sh
    2. Vá no VagrantFile no diretorio que instalou o passo 6.a e edite. 
    3. Descomente a linha: # config.vm.forward_port 80, 8080 e configure para as portas que deseja utilizar no windows quando rodar os projetos. Ex: 
      1. config.vm.forward_port 8000, 8000 
      2. # config.vm.forward_port 9000, 9000
  11. Reinicie o Vagrant com o comando: vagrant reload no seu prompt do windows

O tutorial acima funciona e estou utilizando-o a muito tempo. Depois de um tempo, apareceu a seguinte mensagem:
New release 'precise' available.
Run 'do-release-upgrade' to upgrade to it.

Tentei atualizar e tive problemas. Perdeu-se o compartilhamento da pasta com o Windows, bem como problemas para instalação dos pacotes PIL e MySQL-python.

Resolvi com a reinstalação do começo, sem fazer esta atualização.

hasta!

domingo, 1 de fevereiro de 2009

Parte 6 - Login com autenticação pelo sistema do Django

Neste post veremos como fazer a autenticação com o login do django criado na parte 5.
Primeiro, abra o settings.py do seu projeto e adicione as seguintes linhas abaixo da setting ROOT_URL:




Essa tupla irá passar diretamente para o template os modulos de request, autenticação, debug e internacionalização.

No caso do request, isso poupará muito trabalho nos templates, pois desta forma acessaremos POST, GET e SESSION de forma direta.


Coloque também no settings.py, abaixo das configurações do banco de dados as seguintes settings:

# ESQUEMA DE LOGIN
AUTH_PROFILE_MODULE = 'cadastro.cadastro'
LOGIN_URL = '/cadastro/login/'


Estas settings definem que o módulo de autenticação será o modulo de cadastro e qual é a url para efetuar o login.

Esta url será utilizada mais a frente.


Com o settings.py alterado, deixe o views.py do módulo de cadastro da seguinte forma:



Na linha 3 temos a importação dos metodos de autenticação que utilizaremos.
Para acessar o request de forma direta no template (sem a necessidade de passá-lo em todos os render_to_response) se faz necessário a importação da linha 5 e o parâmetro opcional abaixo para o template em questão:

context_instance=RequestContext(request, {})



Neste exemplo, utilizarei a mesma def para exibir o formulário e para efutar o login. Na linha 10, caso já exista o id do usuário vindo pelo request, significa que o usuário já está logado no sistema, caso contrário irá para o teste seguinte na linha 14.

O metodo authenticate utilizado na linha 17 é o responsável por tentar recuperar o usuário que contenha nos atributos username e password os valores postados pelo formulário. Se o objeto u receber um valor válido para usuário (linha 18) e se o atributo is_active (usuário ativo, linha 19) for True, o método authlogin fará a autenticação para o usuário em questão.

Na linha 22 temos um recurso interessante do Django. Caso seja solicitada uma view que requer login, automaticamente isto será tratado e usuário será redirecionado para o formulário de login (definido na setting LOGIN_URL previamente descrita). Quando o mesmo entrar com usuário e senha, o usuário será redirecionado para o link previamente solicitado que é passado por GET para a variável next. Veremos abaixo como definir que uma view precisará de login.

O Django também já possui implementado o método de logout (linha 30) que tira o usuário logado de todos os atributos da SESSION.

Vamos ver como obrigar o usuário logar para ver um determinado conteúdo. Abra o arquivo cd/views.py e deixe-o da seguinte forma:




Aqui a alteração é bem simples, apenas precisamos importar o decorator login_required com a linha 6, e utilizá-lo logo antes de cada def que desejarmos, como visto na linha 8. Toda vez que a def escolhida for chamada, será feito a verificação de login para a exibição da mesma.



Agora apenas falta criar os htmls e as urls para login. Crie 2 htmls conforme as imagens abaixo:

login.html

logado.html



Crie um arquivo com nome de urls.py dentro da app cadastro da seguinte forma:



Agora basta dar o include das urls de cadastro no urls.py da raiz do projeto:

(r'^cadastro/', include('app.cadastro.urls')),


Rode o projeto com o comando runserver e faça os testes necessários.

svn: Revision 9
hasta!

sábado, 24 de janeiro de 2009

Parte 5 - Integrando o cadastro aos usuários do Django


Neste tópico, mostrarei um dos muitos recursos do Django em detalhes: a Integração do cadastro do projeto ao usuários Django.

Vamos primeiro entender do que se trata. Cadastro é uma das muitas aplicações que geralmente temos em todos os projetos, e muita das vezes, os usuários que se cadastrarem tem acesso privilegiado à algumas seções. Para restringir o acesso não autorizado ao conteúdo controlado, era necessário controlar em todas as páginas se o usuário estava logado, se tinha permissão de fazer àquela requisição, etc.
No Django há uma forma fácil de fazer isso. Vamos ao código. Crie sua aplicação cadastro:

python manage.py startapp cadastro


E deixe o model da seguinte forma:






O relacionamento da classe cadastro recém criada e a de usuários do Django ocorre na linha 11, onde temos uma FK para a classe User, importada na linha 2.

Outra coisa interessante, é a linha 3, onde importamos a lista de estados brasileiros provida pelo próprio Django. Utilizo esta lista na linha 25 para prover uma escolha no campo estado da classe cadastro.

Abaixo da classe meta que vimos nos posts anteriores, temos um método muito importante. A def save é a responsável por fazer a persistencia dos dados no banco. O que estou fazendo nesta classe é simplemente sobrescrevendo ela, de forma a funcionar como preciso.

Quando um objeto é adicionado ao banco, o método save é chamado e instancia um objeto de uma classe, setando os valores passados para cada respectivo atributo.

Caso for sobrescrever a def save, é necessário prever as duas situações: quando um objeto for inserido ou quando for alterado. Em ambos os casos, o o save é chamado.

Para testar qual caso estaremos lidando basta fazer o teste da linha 36:

if not self.id:

Se não existir conteudo dendo do atributo id do objeto atual, o mesmo estará sendo inserido ao banco de dados, caso contrário, alterado.


Neste exemplo utilizaremos o email como usuário. Como o usuário do Django tem que ser único, farei alguns tratar isso. Na linha 37, é feito uma busca no banco de cadastro para verificar se o email já existe no sistema.

c = Cadastro.objects.filter(email=self.email).count()

Caso o email existir (linha 38), levantaremos uma exceção EmailExistente impedir o cadastro.

Veremos como utilizar as excessões mais a frente.

Nas linhas 41 à 47, é feito uma verificação para saber se o usuário já existe. Caso existir, o mesmo é atribuído ao objeto u, caso contrário, é criado um novo usuário com base no email e senha fornecidos e atribuido ao objeto u. Em ambos os casos, o objeto u é salvo e a FK para a classe User é setada com o mesmo.


Para alteração (linhas 48 à 52), basta setar os atributos da classe user com os novos dados forncecidos.


Após este tratamento, será chamado o método save original para fazer a persistência, passando os seguintes parâmetros: a classe Cadastro e nosso objeto em questão (self), da seguinte forma:

super(Cadastro, self).save()


As classes CadastroPF e CadastroPJ, são classes normais iguais as que já foram feitas, com apenas uma diferença: não herdam da models.Model, mas sim da classe Cadastro, onde temos os atributos comuns às duas. Crie o restante das classes conforme a figura abaixo:






Crie um admin.py da seguinte forma:




Note que apesar de criar uma administração pra classe Cadastro, esta não está registrada na administração. Desta forma, apenas será inserido um cadastro de pessoa física ou jurídica, e veremos a herança funcionado.



Instale sua aplicação no settings, sincronize o banco, inicie o servidor e faça os testes necessários.


svn: Revision 8
hasta!


domingo, 18 de janeiro de 2009

Parte 4 - Criando views

Para concluir essa primeira fase do tutorial, faremos agora exemplo com duas views para a aplicação CD.

Abra o arquivo views.py e o deixe da seguinte forma:

# -*- coding: utf-8 -*-
# Create your views here.

from django.shortcuts import render_to_response
from app.cd.models import Interprete, Album

def listaInterpretes(request):

interpretes = Interprete.objects.order_by('nome')
return render_to_response('cds/interpretes.html', {'interpretes':interpretes,})


def listaCds(request,slug=None):

cds = Album.objects.filter(interprete__slug = slug)
return render_to_response('cds/cds.html', {'cds':cds,})

A função render_to_response é a responsável de passar todos os objetos para o template especificado.

Para listar os intérpretes, utilizaremos def listaInterpretes. Todas as defs criadas no views.py para utilização no front precisam do parâmetro obrigátorio resquest. Através dele, será possível pegar conteúdos dos POSTs, GETs e SESSIONs.

A primeira linha da def listaInterpretes, é a responsavél por pegar todos os registros contidos no banco para esta classe e através do método order_by, os registros já virão ordenados pelo campo solicitado, neste caso, o nome.

Ao clicar no nome do intérprete, queremos mostrar quais cds estão relacionados a ele. Faremos isso utilizando a listaCds. Da mesma forma que fizemos com a primeira def, será necessário pegar todos os cds, porém agora temos uma restrição: mostraremos apenas os cds vinculados ao intérprete escolhido.

Vamos enteder como isso será feito:

cds = Album.objects

Neste ponto, temos todos os cds contidos no banco de dados. Para filtrar apenas os relacionados ao intérprete escolhido utilizaremos o método filter.

Nossa chave estrangeira interprete da classe Album é uma conexão direta aos objetos da classe Interprete, sendo possivel desta forma acessar quaisquer conteudos lá contidos.

Lembra do campo slug do model? Aqui ele será utilzado. Cada intérprete possui um slug, e como ele estará contido na url, por que não utilizá-lo para o filtro? É extamente isso que iremos fazer.

No comando filter, vamos filtrar pelo campo slug da classe Interprete da seguinte forma:

filter(interprete__slug = slug)

O parâmetro slug desta def será passado pela url. Com as defs prontas veremos agora como criar tais urls para deixá-las elegantes e funcionais.

O URLS.PY

Adicone ao urls.py da raiz do seu projeto a seguinte linha abaixo da url do admin:

(r'^cds/', include('app.cd.urls')),

Esta linha importará todas as urls contidas no urls.py da sua aplicação cd. É possivel colocá-las no arquivo urls.py da raiz, mas por questão de organização, criaremos um outro urls.py dentro da aplicação, referenciando as mesmas través do include acima, mapeadas pela url: /cds/.

Agora crie dentro da pasta cd, um arquivo chamado urls.py e deixe-o da seguinte forma:



from django.conf.urls.defaults import *

urlpatterns = patterns('app.cd.views',

(r'^$', 'listaInterpretes'),
(r'^interpretes/$', 'listaInterpretes'),
(r'^(?P<slug>[-\w]+)/$', listaCds),

)


Com as importações necessárias, definiremos os padrões de urls desta aplicação.
Neste exemplo estão sendo criadas três urls:

  • /cds/
    Irá funcionar de maneira similar ao index.html em uma pasta qualquer. Essa urls chamará a def listaInterpretes contidas no views.py da aplicação cd.

  • /cds/interpretes/
    Esta url terá a mesma funcionalidade da anterior.

  • /cds/
    Aqui, o slug do intérprete será passado através da expressão regular para texto : [-\w]+ , que chamará a def listaCds, passando o segundo parâmetro necessária para a listagem de cds: o slug do intérprete.

OS TEMPLATES

Criarei os dois templates dos exemplos acima de forma bem simples, apenas para servir de exemplo.

Dentro da pasta templates na raiz do projeto crie a pasta cds. Dentro dela crie os dois arquivos abaixo:

interpretes.html



Na linha 14 da imagem a acima, temos um for que irá passar por todos os registros vindos o objeto interepretes que foi passado na view. Para cada registro, será criado um link para redirecionar até SLUG/, onde o mesmo será o valor contido no atributo slug do objeto i corrente.
Conforme vimos anteriormente, o parâmetro slug, será passado através da expressão regular contida no urls.py que foi criado na aplicação.

Vejamos o outro template a ser criado:


cds.html


Neste template, apenas temos um for, que irá correr todos os registros do objeto cds filtrados pelo slug do intérprete, conforme vimos na view.


OBSERVAÇÕES:

  • Note que as variáveis apenas são ACESSADAS no template, não é possivel definí-las no mesmo.

  • Para os comandos, deve-se utilizar o bloco:
    {% comando %} com seu respectivo bloco de fechamento {% endcomando %}.

  • Para acessar o conteúdo dos objetos deve-se utilizar: {{ obj.atritbuto }}, conforme nos exemplos acima.

Agora basta iniciar o servidor e acessar http://localhost:8000/cds/, se estiver rodando local.

Repositório atulizado até este post: Revisao 7.

hasta!

sexta-feira, 16 de janeiro de 2009

Parte 3 - Criação da primeira APP

Dentro da pasta do projeto iremos criar a primeira aplicação deste projeto. Começarei por CD. Navegue até a pasta do projetop via prompt e execute o comando:

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.

quinta-feira, 15 de janeiro de 2009

Parte 2 - Breve tour pelo admin do Django

Continuando de onde parei no último post, uma funcionalidade muito útil que o Django já trouxe pronto: A administração de usuários.

Como é bem auto explicativo, apenas vou apresentar brevemente como ficou o admin criado. Depois de logar, verá a home da administração. É nela que estarão todas suas aplicações instaladas. Como acabamos de criar o admin, este contém apenas o módulo padrão Site, que já vem configurado no settings.py na setting INSTALLED_APPS, conforme vimos na parte 1.

O módulo Auth é o módulo que adiconamos à INSTALLED_APPS quando configuramos o settings.py do projeto. É ele o responsável por gerenciar todos os logins e permissões de usuários e grupos, o que se integrado com o usuário do front-end, facilita muito o desenvolvimento. Veremos como integrar o usuário do Django com um usuário do projeto mais a frente.



Também na home, é apresentado um box a direita que mantém o historórico das modificações realizadas recentemente na administração.


Home da administração


Pré-cadastro dos usuários


Para utilizar a administração o usuário orbigatoriamente precisa ser um Membro da equipe. Automáticamente quando cria-se um usuário este vem com a opção ativo pré-selecionada. Este recurso é bastate util caso não queira perder as informações do usuário em seu projeto, como por exemplo um E-Commerce que existam vários pedidos associados a este usuário, caso precise "removê-lo", pense na simples opção de desativá-lo, porque SIM, com o Django nada fica órfão no banco.



Permissões

Outra facilidade que o Django provê é a customização das permissões por usuários e grupos. Sobre as permissões existem três opções: ou cria-se um usuário com privilégio de superusuário (o que poupa o trabalho de setar todas as permissões individualmente), ou caso precise de apenas algumas pode setá-las com base na lista de permissões. Esta lista também vai apresentar todas as aplicações que você instalar no seu projeto, ou ainda criar um grupo e setar apenas as permissões do grupo. Os usuários que forem associados ao grupo em questão herdarão as permissões do mesmo.

Edição de permissões


Precisa de um grupo e agora já digitou todas as informações do seu usuário? Sem problemas. É possivel utilizar o símbolo de "+" ao lado da lista de grupos, sem a necessidade de voltar à home para criar o grupo pelo módulo de grupos. Ao criar um grupo por aqui, além de ele já ser adicionado ao banco, ao clicar em salvar, o Django automaticamente o seleciona para a concluir a crição do usuário. Veremos como fazer isso quando criarmos a primeira aplicação.

Adicionando grupos pela administração de usuários



Atalhos, buscas e filtros com uma linha de código.

Listagem dos usuários com alguns recursos interessantes


Insira um usuário, edite as permissões, logue com ele para ver as diferenças para sentir uma das várias facilidades que teremos para os projetos.

hasta!

terça-feira, 13 de janeiro de 2009

Parte 1 - O Projeto

Defini como projeto, algo genérico suficiente para podermos seguir de maneira fácil e possibilitar adpatções conforme for o desenrolar do mesmo.
Utilizarei no meu exemplo, um sitema para gerenciar cds, dvds e livros de um colecionador.

O INÍCIO

Crie uma pasta para armazenar seus projetos, de preferência um lugar fácil para acessar via prompt (Ex. C:\Projetos). Para criar seu projeto vá até sua pasta de projetos e digite o comando:

django-admin.py startproject app

Neste exemplo, adoto por padrão o nome app para meu projeto. Mais a frente entrarei em detalhes sobre isso.

Ao executar o comando, na sua pasta de projetos será criada uma pasta com o nome do projeto escolhido e dentro dela 4 arquivos:
  • __init__.py
    Este arquivo não será utilizado por hora, mas ele serve para informar ao django que é uma pasta com conteúdo Python.

  • manage.py
    Este arquivo será utilizado mais a frente quando for criar as aplicações para o projeto

  • settings.py
    Este arquivo é o responsável por gerenciar todas as configurações do seu projeto. Entraremos em mais detalhes abaixo.

  • urls.py
    Este arquivo conterá todas as urls de nossas aplicações mapeadas para suas respectivas views.

O SETTINGS.PY

Abra o settings.py da raiz do projeto. Por hora, irei alterar apenas o básico de forma a colocar o administrativo gerado pelo django com poucas alterações:

coloque o seguinte comando na primeira linha do seu arquivo:

from os import path as os_path

Nesta linha, estou importando o objeto path do pacote os, e colocando um alias para tal: os_path. Utilzaremos isso logo a seguir para configurar o media.


Os controles de debug servem para o django gerar uma tela erro ao desenvolvedor informando o motivo do erro. Mais a frente tratarei dos erros mais comuns de cometer durente o desenvolvimento. Por hora, deixe as duas linhas como estão:

DEBUG = True TEMPLATE_DEBUG = DEBUG


Vamos criar duas setting neste ponto para definir o caminho e a url do projeto. Coloque os comandos a seguir abaixo dos controles do DEBUG.

PROJECT_PATH = os_path.abspath(os_path.split(__file__)[0])
SITE_URL = 'http://localhost:8000/'



Certifique-se que a setting SITE_URL tenha uma barra no final conforme o código acima.

Logo em seguida está uma tupla com os administradores do seu projeto. Coloque seu nome e seu email. nos respectivos lugares e descomente a linha. Isso será util mais a frente quando for colocar para enviar os logs de erros para o email. Deixe seu código assim:

ADMINS = ( ('Seu nome aqui', 'seuemail@provedor.com.br'), )

VALE LEMBRAR:

A indentação para indicar que os elementos hierarquicamente dispostos têm o mesmo avanço relativamente à posição (x,0). Na maioria das linguagens a indentação tem um papel meramente estético, tornando a leitura do código fonte muito mais fácil (read-friendly), porém é obrigatória em outras. Python, por exemplo, utiliza esse recurso tornando desnecessário o uso de certos identificadores de blocos ("begin" e/ou "end").

Para este tutorial utilizarei UM TAB, para cada nível de indentação


O Banco de Dados

Crie uma database no seu banco de dados e configure cada variável com seu respectivo valor conforme o exemplo abaixo:


DATABASE_ENGINE = 'mysql'
DATABASE_NAME = 'app'

DATABASE_USER = 'usuario'

DATABASE_PASSWORD = 'senha'

DATABASE_HOST = '' # deixe vazio para localhost

DATABASE_PORT = '' #deixe vazio para porta padrao do banco escolhido. Neste caso 3306.



O usuário informado acima deve ter privilégios para criação/alteração de tabelas, indices etc., na database informada.

Acerte também o fuso horário que deseja utilizar:

TIME_ZONE = 'America/Sao_Paulo'

Outro recurso muito interessante é a internacionalização. O Django já provê uma serie de facilidades para deixar seu projeto multi-lingua. Mais a frente , mostro como funciona a traduçãio automática. Coloque o idioma padrão aqui:
LANGUAGE_CODE = 'pt-Br'

O próximo setting é o ID do site que está trabalhando. Com o django é possível utilizar a mesma administração pra projetos semelhantes porém independentes, gerenciando através desta setting. Deixe ela sem nenhuma alteração como descrito abaixo:

SITE_ID = 1

A próxima setting é referente a internacionalização. Deixe ela como True que iremos utilizá-la mais a frente.

USE_I18N = True


O MEDIA

O media é onde ficarão todos os arquivos referentes a conteúdo, como por exemplo
  • páginas de estilos (css)
  • javascripts
  • todos os arquivos vindos de upload pela administração, tais como fotos, videos, pdfs, etc.
A correta configuração do media se faz necessária para acessar os conteúdos descritos acima. Para definir um padrão de configuração, vamos utilizar a setting PROJECT_PATH, defina anteriormente. Deixe a configuração do media da seguinte forma:

  1. MEDIA_ROOT = os_path.join(PROJECT_PATH, 'media')
  2. MEDIA_URL = '%smedia/' % SITE_URL # trailing slash
  3. ADMIN_MEDIA_PREFIX = '%smedia/' % SITE_URL # trailing slash.

No item 1, usaremos o método join do objeto os_path previamente importado para concatenar o caminho do projeto com a string media. Já no item 2, será definido a url do media. O conteudo de %s será substituido pela setting SITE_URL (outra forma de concatenação de strings), também previamente definida. E por fim, no item 3, o caminho do media para o administrativo, igualmente definido no item 2.

Para o administrativo do django, não é necessário ter uma pasta media dentro do seu projeto. Farei isso mais a frente quando criar uma aplicação que precisará disso.

A setting SECRET_KEY, faz parte do algoritmo de criptografia que o django utiliza para gerar senhas por exemplo. Deixe esta setting sem nenhuma alteração.


A tupla MIDDLEWARE_CLASSES define quais middlewares serão utilizados pelo projeto, por default 3 deles já vem adicionados a lista e por hora são apenas os necessários. Deixe esta settings também sem nenhuma alteração.


ROOT_URLCONF define qual será o arquivo de urls utilizado pelo projeto. No caso usaremos o criado na raiz do projeto. Por default, essa setting já vem com esse valor, apenas confira para checar:

ROOT_URLCONF = 'app.urls'


A tupla TEMPLATE_DIRS é a responsável por mapear os possíveis caminhos para seus templates que serão utilizados nas views de suas aplicações e/ou alguma view personalizada no admin. Este tópico será discutido mais a frente.
Deixe a tupla da seguinte forma:

TEMPLATE_DIRS = ( os_path.join(PROJECT_PATH, 'templates') )


E por fim, a setting INSTALLED_APPS é a tupla que contém todas as aplicações instaladas do seu projeto. Vale destacar que se desenvolvido corretamente uma aplicação, é possivel torná-la plugável e utilizá-la em outros projetos de forma fácil e rápida.
Por hora apenas adicione a aplicação dos usuarios do admin:

INSTALLED_APPS = (


'django.contrib.auth',

'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',

'django.contrib.admin', #linha que adiciona o admin

)


Com o settings.py configurado, vá ao promtp, navegue até a pasta do seu projeto (C:\Projetos\app) e execute o seguinte comando para a criação do banco:

python manage.py syncdb

Isto irá criar todas as tabelas das aplicações instaladas, com relacionamentos, indices e de uma maneira otimizada.

Após a criação das tabelas, digite yes quando for questionado se deseja criar um super-usuário. Prencha os dados conforme forem solicitados.

Este usuário é o primeiro usuário com acesso ao administrativo. Trataremos da administração de usuários na Parte 2.


Para definirmos a url da administração, abra o urls.py e descomente as seguintes linhas linhas:

from django.contrib import
admin
admin.autodiscover()



e dentro de urlpatterns, descomente a url do admin:

(r'^admin/(.*)', admin.site.root),

No servidor de teste local do Django, é necessário informar que os conteudos da pasta media são conteudos estáticos.

No urls.py deixe o início do arquivo da seguinte forma:

from django.conf.urls.defaults import *
from django.conf import settings
from os import path as os_path


Ainda no urls.py coloque o seguinte código no final do arquivo:

if settings.DEBUG:


urlpatterns += patterns('',

(r'^media/(.*)$', 'django.views.static.serve', {'document_root': os_path.join(settings.PROJECT_PATH, 'media')}),)




Mais uma vez tome cuidado com a indentação.
Feito isso, vá até a pasta onde fez o checkout do Django (C:\Django\), e copie as seguintes pastas:

C:\Django\django\contrib\admin\media C:\Django\django\contrib\admin\templates

Agora vá até a raiz do seu projeto e cole-as.


Volte ao prompt e digite o seguinte comando para iniciar o servidor inbutido no django para testes:

python manage.py runserver

Com tudo corretamente configurado, você dever receber uma mensagem semelhante à:

Django version 1.1 pre-alpha, using settings 'app.settings'
Development server is running at http://127.0.0.1:8000/

Quit the server with CTRL-BREAK.



Pronto! Já temos o servidor do django rodando local para testes.
Vá ao navegador e digite o seguinte endereço:

http://localhost:8000/admin/

Com tudo rodando perfeitamente, você verá uma tela conforme a apresentada na Figura 1:


Figura 1. Interface de login da administração do Django


Caso queira ver tudo o que foi feito neste passo, acesse a administração com o super-usuário criado.

Na próxima parte, será explicado detalhes sobre a administração.

hasta! =D