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!

quinta-feira, 14 de agosto de 2014

Gerando um PDF em Django sem template e forçando seu donwload

Você vai precisar dos seguintes aplicativos instalados no ENV:
  • reportlab==2.7

Faça uma view conforme abaixo:

#############################################################
# PDF
#############################################################
class PDFView(View):

 def post(self, request, *args, **kwargs):
  # IMPORTS NECESSARIOS
  from reportlab.pdfgen import canvas
  from reportlab.lib.pagesizes import letter, landscape, A4
  from reportlab.lib.units import inch, cm
  from reportlab.lib.colors import HexColor
  from django.conf import settings
  import os

  # VALIDAÇÃO DO CSRF_TOKEN
  c = {}
  c.update(csrf(request))
  
  # NOME DO ARQUIVO
  nome_arquivo = "1.pdf"
  arquivo = '%s/uploads/%s' % (settings.MEDIA_ROOT, nome_arquivo)

  if os.path.isfile(arquivo):
   # REDIRECT CASO NÃO ENCONTRAR O ARQUIVO
   return redirect('/')

  imagem =  '%s/%s' % (settings.MEDIA_ROOT, "sua_imagem_aqui.jpg")

  # CRIAÇÃO DO PDF EM MODO PAISAGEM , TAMANHO A4
  c = canvas.Canvas(arquivo, pagesize=landscape(A4))
  c.drawImage(
   '%s' % imagem,
   0,
   0,
   29.7*cm,
   21*cm
  )

  # DEFINIÇÃO DE FONTE, FAMILIA, TAMANHO E COR
  c.setFont("Helvetica", 16)
  c.setFillColor(HexColor(0x094d8a))

  # ESCRITA DO TEXTO POR CIMA DA IMAGEM COM ALINHAMENTO
  c.drawString(18.4*cm, 14*cm, "%s" % participante.nome)

  # GERAÇÃO E CRIACAO DO PDF
  c.showPage()
  c.save()

  # REDIRECT PARA VIEW QUE FORCARÁ O DOWNLOAD
  return redirect('certificados:download',participante.id)

 def get(self, request, *args, **kwargs):
  return redirect('/')


#############################################################
# DOWNLOAD
#############################################################
class ForceDownload(View):
 def get(self, request, *args, **kwargs):
  from django.http import HttpResponse
  from os import path
  
  import mimetypes

  arquivo = '%s/uploads/%s.pdf' % (settings.MEDIA_ROOT, kwargs['pk'])

  if not (path.exists(arquivo)):
   raise Http404

  mimetype, encoding = mimetypes.guess_type(arquivo)

  if mimetype is None:
   mimetype = 'application/force-download'

  file = arquivo.split("/")[-1]

  response = HttpResponse(open(arquivo, 'r').read())
  response['Content-Type'] = mimetype
  response['Pragma'] = 'public'
  response['Expires'] = '0'
  response['Cache-Control'] = 'must-revalidate, post-check=0, pre-check=0'
  response['Content-Disposition'] = 'attachment; filename=%s' % file
  response['Content-Transfer-Encoding'] = 'binary'
  response['Content-Length'] = str(path.getsize(arquivo))
  return response # Create your views here.


E no urls deixe da seguinte forma:


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

urlpatterns = patterns('',

 ############################################################################
 # DOWNLOADS
 ############################################################################
 url(r'^downloads/(?P<pk>\d+)/$', views.ForceDownload.as_view(), name='download'),

 ############################################################################
 # CERTIFICADO
 ############################################################################
 url(r'^(?P<slug>[-\w]+)/$', views.PDFView.as_view(), name='pdf_detail'),


)

hasta!

quarta-feira, 2 de julho de 2014

Como fazer a contrab trabalhar pra você

Normalmente quando é necessário uma tarefa repetitiva e que possui um certo grau de integração com outros serviços, utilizo o recurso da contrab.

No python basta criar seu arquivo e definir nele o que será feito. Em seguida basta agendar a tarefa na crontab de acordo com a periodicidade necessária.

Para listar as tarefas agendadas na cron basta executar o comando:
crontab -l

Para criar/editar tarefas basta executar o comando:
crontab -e

Vale ressaltar que caso nao goste do editor que a cron utiliza, pode trocar por algum  de sua preferencia, como o nano, basta executar o seguinte comando:

export VISUAL=nano

Para definir o tempo que você pode fornecer valores para minutos, horas, dias do mes, meses e dias da semana. Nesta ordem. Também é possível definir * para qualquer um destes parametros de forma a referenciar qualquer valor.

Outra coisa que vale dizer é : Se vc precisa executar uma rotina que precisa de mais de um comando , certifique-se que todas as linhas sejam aglutinadas em apenas uma, através do &&.

Exemplo:

# m h  dom mon dow   command

0 * * * 1,2,3,4,5 . /ENV/bin/activate && python carga.py && deactivate

O comando acima roda sempre que os minutos forem iguais a 0, para todas a horas, em todos os dias do mês, durante todos os meses e somente de segunda a sexta. Ele inicia o  ambiente virtual, executa o arquivo carga.py e desativa o ambiente virtual.