Mostrando postagens com marcador plugins-uteis. Mostrar todas as postagens
Mostrando postagens com marcador plugins-uteis. Mostrar todas as postagens

sexta-feira, 12 de agosto de 2016

Plugins Úteis: django-image-cropping - Como incoporar uma ferramenta de recorte para fotos no admin


Imagine que temos um projeto onde o usuário, responsável por alimentar os conteúdos, não tem a mínima noção do tamanho da imagem necessária para não destruir o layout, e nenhum pouco de boa vontade para ler a especificação do tamanho no help_text?

Claro que sempre dá pra fazer o recorte automático com o sorl-thumbnail, mas e se o usuário quiser escolher como recortar a foto?

Bom, pra isso, apresento-lhes o impressionante : django-image-cropping.


Vejamos como utilizar:

1. Primeiramente, instale ele no seu virtualenv:

pip install django-image-cropping

2. Se não tiver o easy_thumbnails instalado, instale:

pip install easy_thumbnails 

3. Adicione os dois no INSTALLED_APPS:

INSTALLED_APPS = [
    ...
    'easy_thumbnails',
    'image_cropping',
    ...
]

4. Adicone também no settings.py:

from easy_thumbnails.conf import Settings as thumbnail_settings
THUMBNAIL_PROCESSORS = (
    'image_cropping.thumbnail_processors.crop_corners',
) + thumbnail_settings.THUMBNAIL_PROCESSORS

5. No seu model que quiser a função de recorte no admin deixe como a seguir:

from image_cropping import ImageRatioField

class SeuModel(models.Model):
    ...
    imagem = models.ImageField(upload_to="/caminho/para/upload/",)
    cropping = ImageRatioField('imagem', '900x900')
    ...


Mude a proporção do atributo cropping de acordo com sua necessidade.

6. No admin.py:

from django.contrib import admin
from image_cropping import ImageCroppingMixin

class SeuModelAdmin(ImageCroppingMixin, admin.ModelAdmin):
    pass

admin.site.register(SeuModel, SeuModelAdmin)

7. No template que for exibir a foto recortada utilize a tag provida pelo plugin:

{% cropped_thumbnail instancia_do_seu_model "cropping" [scale=INT|width=INT|height=INT|max_size="INTxINT"] %}

EX:
<img cropping="" scale="0.5" src="{% cropped_thumbnail instancia_do_seu_model " />


8. Dá inclusive para utilizar esse plugins para Inlines:


from image_cropping import ImageCroppingMixin
class ImagemInline(ImageCroppingMixin, admin.TabularInline):
 model = Imagem
 extra = 0



Desta maneira, ao fazer o upload, o usuário poderá selecionar a área de recorte diretamente no admin, respeitando a proporção imposta no models.py e sem destruir o layout.


Fonte e mais informações: https://pypi.python.org/pypi/django-image-cropping


hasta!

sexta-feira, 25 de setembro de 2015

Plugins Úteis: django-geoposition - Como incorporar o google maps dentro do admin para geolocalização

Precisa incorporar um mapa com base em um endereço no administrativo para exibir no front? Tarefa simples pro django-geoposition (https://github.com/philippbosch/django-geoposition).

A instalação é simples:
pip install django-geoposition

Coloque a linha abaixo no seu arquivo settings.py, em INSTALLED_APPS:
INSTALLED_APPS = (
    ...
    'geoposition',
    ...
)

Outra configuração que vale a pena fazer, é incluir no seu arquivo settings.py as linhas abaixo para definir o zoom:
GEOPOSITION_MAP_OPTIONS = {
    'minZoom': 15,
    'maxZoom': 18,
}

No seu arquivo models.py, deixe como a seguir:
from geoposition.fields import GeopositionField
from localflavor.br.br_states import STATE_CHOICES

class SuaClasse(models.Model):
 """(Unidade description)"""
 endereco = models.CharField(max_length=255, verbose_name=u'Endereço', help_text='Para uma melhor localização no mapa, preencha sem abreviações. Ex: Rua Martinho Estrela,  1229') 
 bairro = models.CharField(max_length=255,)
 cidade = models.CharField(max_length=255,help_text="Para uma melhor localização no mapa, preencha sem abreviações. Ex: Belo Horizonte")
 estado = models.CharField(max_length=2, null=True, blank=True,choices=U.STATE_CHOICES)
 position = GeopositionField(verbose_name=u'Geolocalização', help_text="Não altere os valores calculados automaticamente de latitude e longitude")

 class Meta:
  verbose_name, verbose_name_plural = u"Sua Classe" , u"Suas Classes"
  ordering = ('endereco',)

 def __unicode__(self):
  return u"%s" % self.endereco 

No administrativo será gerado tudo automático, mas existem algumas melhorias que podem ser feitas pra ficar ainda mais bacana. Inclua o arquivo css e js abaixo que em seguida explico como faremos.
# coding: utf-8
from django import forms
from django.contrib import admin
from .models import *


class SuaClasseForm(forms.ModelForm):
 class Media:
  css = {
   'all': ('admin/css/geoposition_override.css',)
  }
  js = ('admin/js/geoposition_override.js',)

class SuaClasseAdmin(admin.ModelAdmin):
 form = SuaClasseForm
 search_fields = ('endereco', 'cidade',)
 list_display = ('endereco', 'cidade','estado','bairro')
 list_filter = ['estado',]
 save_on_top = True



admin.site.register(SuaClasse, SuaClasseAdmin)

No arquivo css adicionado (geoposition_override.css), iremos ocultar o campo de busca do mapa, e utilizaremos nossos próprios atributos da classe para tal, mesmo porquê, o atributo position irá só gravar em banco a latitude e longitude e não o endereço pesquisado.

Crie um arquivo dentro de <STATIC_DIR>/admin/css, chamado geoposition_override.cssm, e nele coloque simplemente a linha abaixo:

.geoposition-search input{display:none;}

Agora, crie um js chamado geoposition_override.js na pasta <STATIC_DIR>/admin/js com as linhas abaixo:
django.jQuery(document).ready(function($) {
 $('#id_position_0, #id_position_1').attr('readonly', 'readonly');

 $('#id_endereco, #id_cidade, #id_estado').blur(function(event) {
  /* Act on the event */
  if ($('#id_endereco').val()!='' && $('#id_cidade').val()!='' && $('#id_estado').val()!='') {
   $('.geoposition-search input').val($('#id_endereco').val()+' ' +$('#id_cidade').val()+' '+$('#id_estado').val());
   
   // TRIGGER DO ENTER PARA EXECUTAR A BUSCA
   var e = $.Event("keydown");
   e.which = 50; // # Some key code value
   $(".geoposition-search input").trigger(e);
  };
 });
});

E o resultado:

hasta!

sexta-feira, 14 de agosto de 2015

Plugins Úteis: django-auditlog - Ótima solução para registro de logs



Precisa de um registro de logs para todas as alterações realizadas em um sistema? Isso normalmente é necessário para sistemas que sofrerão auditoria.

O caminho das pedras é duro, alterar todas as views, fazer os registros manualmente, coonsiderar se quer apenas registrar qual atributo foi alterado ou pior, registrar qual era a informação antiga e qual é a informação nova de cada atributo. Trabalhoso? Muito.

Eis que surge o django-auditlog (https://github.com/jjkester/django-auditlog). Com ele o log fica bem completo e é muito fácil de configurar.

Você vai precisar de:
  • Python 2.7 ou 3.4 
  • Django 1.7 ou 1.8 

Vamos a um passo a passo bem simples para colocar o plugin pra funcionar:


1. Instale ele no seu virtualenv:
pip install django-auditlog

2. Adicione ele na setting INSTALLED_APPS:
...
'auditlog'
...

3. Rode o comando migrate para criar as tabelas necessárias no banco:
manage.py migrate

4. Adicione a linha abaixo na setting MIDDLEWARE_CLASSES:
...
'auditlog.middleware.AuditlogMiddleware'
...

5. Pronto, agora é só registrar os modelos que quer manter o histórico de mudanças como no examplo abaixo:
from auditlog.registry import auditlog
from django.db import models

class MyModel(models.Model):
    pass
    # Model definition goes here

auditlog.register(MyModel)


Depois de tudo configurado, terá sido criado uma tabela no seu banco de dados com o nome de auditlog_logentry,  com os seguintes campos:

  • id
  • object_pk
  • object_id
  • object_repr
  • action
  • changes
  • timestamp
  • actor_id
  • content_type_id
  • remote_addr
  • additional_data


Algumas considerações importantes:

  • object_pk e object_id armezenam a chave primária e o id do registro em questão. Caso sua classe não possua uma chave primária definida, estes dois atributos terão o mesmo valor: a chave primária ID criada automaticamente pelo Django na ausencia de uma definida.
  • object_repr será o valor definido no método __unicode__ da classe do objeto em questão.
  • action será um valor númerico (0,1 ou 2), onde o mais valor é considerado a atividade mais intrusiva no banco, logo em ordem temos: Inserção (0), Alteração (1)  e Remoção (2)
  • changes armazena as mudanças feitas na forma de um dicionário, onde cada chave  será o atributo alterado e terá uma lista com dois valores associado, o antigo e o novo. Ex:
    • {"ultima_troca_senha": ["2015-01-13", "2015-08-13"], "senha": ["1234567", "123456"]}
  • timestamp registrará o momento da mudança no formato datetime, yyyy-mm-dd h:i:s
  • actor_id armazena o id do usuário logado que fez a alteração. Caso haja em algum momento alteração do model registrado e o usuário não estiver logado, este atributo será nulo. Este campo faz referência ao model User utilizado pelo django, na tabela auth_user.
  • content_type_id armazena o id do content_type, fazendo referência ao model ContentType utilizado pelo django, na tabela django_content_type.
  • remote_addr registra o ip do usuário que fez a mudança
  • additional_data armazenará informações adicionais, sendo nulo no registro automático exemplificado acima.



Para mais infrmações, consulte a documentação: http://django-auditlog.readthedocs.org/en/latest/

hasta!

sexta-feira, 21 de novembro de 2014

Plugins Úteis - Color picker no Django Admin

Que tal um color picker parao admin quando precisar selecionar uma cor e ter certeza que o usuário não faz ideia do que #0000FF quer dizer?

Simples.

Você vai precisar de um plugin:
pip install django-paintstore


models.py

No seu models.py deixe como a seguir:

# coding: utf-8
from django.db import models
from paintstore.fields import ColorPickerField

# Create your models here.
class SUA_CLASSE(models.Model):
 """(SUA_CLASSE description)"""
 ...
 cor = ColorPickerField(help_text="Clique no campo para abrir o colorpicker.", max_length=7)
 ...

admin.py

E deixe o admin.py deixa como abaixo:

# coding: utf-8
from django.contrib import admin
from django import forms

from .models import *
# Register your models here.

class SUA_CLASSEForm(forms.ModelForm):

 class Media:
  css = {'all': ('/static/paintstore/css/colorpicker.css','/static/site/js/plugins/paintstore/init.css')}
  js = (
   '/static/paintstore/jquery_1.7.2.js',
   '/static/paintstore/colorpicker.js',
   '/static/site/js/plugins/paintstore/init.js',
  )
 class Meta:
  model = SUA_CLASSE
  fields = '__all__'

class SUA_CLASSEFormAdmin(admin.ModelAdmin):
 form = SUA_CLASSEForm
 
admin.site.register(SUA_CLASSE, SUA_CLASSEAdmin)


RESOURCES:


Os arquivos referenciados acima estão abaixo, salve-os e altere os caminhos no Form, conforme necessidade:

init.js

jQuery(document).ready(function($) {
 $('#id_cor').ColorPicker({
  onSubmit: function(hsb, hex, rgb, el, parent) {
   $(el).val('#' + hex);
   $(el).ColorPickerHide();
   $(el).css({
    color: ''+$('#id_cor_titulo').val(),
    backgroundColor: '#'+hex
   });
  },
  onBeforeShow: function () {
   $(this).ColorPickerSetColor(this.value);
  }
 }).bind('keyup', function(){
  $(this).ColorPickerSetColor(this.value.replace('#', ''));
 });

 $('#id_cor,').css({
  color: ''+$('#id_cor_titulo').val(),
  backgroundColor: $('#id_cor_titulo').val()
 });
});

init.css

#id_cor{
 width:50px;
 background-color:red;
 cursor:pointer;
 color:black;
 border:solid 1px black;
}

segunda-feira, 17 de outubro de 2011

Plugins Úteis - Sorl e o (muito util) ThumbnailField

Para quem utiliza a fantástica biblioteca Sorl Thumbnail (http://pypi.python.org/pypi/sorl-thumbnail), tem uma funcionalidade muito útil além da inclusion tag {% thumbnail %}

Com a inclusion tag, é possível redimensionar e/ou cortar, uma imagem de acordo com a necessidade. Para isso, basta utilizar assim no seu template:

{% load thumbnail %}

A linha acima deve ser colocar no começo do arquivo para carregar as tags da sorl para seu template. E para a imagem fazemos:

<img src='{% thumbnail seu_objeto.campo_foto 150x150 crop,upscale %}' />

Aqui temos um exemplo em que será gerada uma imagem de 150px de largura por 150px de altura. As opções crop,upscale são opcionais e servem para corte e redimensionamento, respecticamente.

Há uma certa desvantagem em utilizar desta forma. A thumb somente será gerada quando alguma requisição for feita para a página, e após isso o arquivo físico da thumb é gerado em tempo de execução. Posteriormente, se a thumb não for trocada, o sistema utiliza a thumb gerada na primeira requisição ao invés de gerar uma nova.

Uma outra opção, e fazer a geração de todas as thumbs utilizadas para uma mesma foto, no momento que a foto é inserida ou alterada. Para isso temos o ThumbnailField.

No seu model, já com a sorl instalada no seu projeto e/ou no virtualenv, faça:

No ínicio do arquivo models.py que for utilizar thumbs, import o ThumbnailField:

from sorl.thumbnail.fields import ThumbnailField

E na sua classe, crie o campo com o campo importado da seguinte forma:

class SuaClasse(models.Model):
    foto = ThumbnailField(
upload_to="uploads/banners/home/%Y",
help_text=u"Tamanho mínimo e proporcional a 1024x768",
options = ('upscale',),
size = (1920,1000),
generate_on_save = True,
extra_thumbnails={
'1024x768':{ 'size':(1024,768), 'options':('upscale',) },
'1280x1024':{ 'size':(1280,1024), 'options':('upscale',) },
'1280x800':{ 'size':(1280,800), 'options':('upscale',) },
'1440x900':{ 'size':(1440,900), 'options':('upscale',) },
'1366x768':{ 'size':(1366,768), 'options':('upscale',) },
},

Deste modo, teremos 6 arquivos para cada imagem que for inserida.

  • A original foto,  que terá no máximo 1920x1000 px de tamanho, sendo que fará uso do upscale
  • E 5 extra_thumbnails, onde cada uma terá um tamanho próprio, também utilizando o upscale.

No template para utilizar o campo foto,  nada muda, continua sendo :

{{ seu_obj.foto }}

Já para acessar alguma das thumbs, utilize:

{{ seu_obj.foto.extra_thumbnails.NOME_DO_THUMBNAIL }} ,  por exemplo:

{{ seu_obj.foto.extra_thumbnails.1280x1024 }} 


Em alguns casos temos que acessá-los em uma view, seja para montar um json para o ajax, ou até mesmo um xml pro inútil e arcaico Flash. Para isso utilize:

seu_obj.foto.extra_thumbnails_tag['1280x800']


Outra opção é criar um model, muito útil para quando deseja-se mostrar a thumb no change list do admin. Para isso, utilize:


def thumb_admin(self):
from sorl.thumbnail import get_thumbnail
im = get_thumbnail(self.imagem, '120x120', crop='center', quality=99)
if im:
return  '<a href="%s/"><img src="%s" alt="Imagem" /></a>' % (self.id, str(im.url))
return  'Sem foto'
thumb_admin.is_safe = True
thumb_admin.allow_tags = True
thumb_admin.short_description = 'Thumb'


hasta!








sexta-feira, 23 de setembro de 2011

Plugins Úteis - South - Uma app para Django muito útil para gerenciamento do Banco de Dados


South

South é uma aplicação do django responsável por gerenciar as modificações feitas no projeto que influenciam em criação/edição/remoção de tabelas e/ou campos no banco de dados.

Para instalar o south no ambiente:
pip install south
adicionar ele na installed_apps

Com o South NÃO DEVE-SE USAR o syncdb do django para criação das tabelas de suas apps. Apenas deve ser rodado o syncdb para criação das tabelas referente as aplicações padrões do settings e mais a do south. 

Para criação das tabelas de uma nova aplicação utilizar:
python manage.py schemamigration NOME_DA_APP --initial

Para criação de todas as tabelas do projeto, basta omitir o nome da app.

Os comandos acima vão criar apenas os schemas de migração, nada será alterado no banco de dados. Para aplicar as migrações deve-se utilizar o comando:
python manage.py migrate NOME_DA_APP

Para todos os esquemas, basta omitir o nome da app.

Depois da situação inicial criada, caso haja necessidade de adicionar/remover campos nos models, utilizar seguinte comando para sincronizar os schemas:
python manage.py schemamigration NOME_DA_APP --auto

E para aplicar as migrações da mesma forma descrita anteriormente:
python manage.py migrate NOME_DA_APP

Caso deseje aplicar o South em algum projeto que não tenha, e as tabelas já tenham sido criadas, basta instalar o South como descrito acima, e utilizar o comando:
python manage.py convert_to_south NOME_DA_APP 


O south cria no banco de dados algumas tabelas para controle do que já foi migrado para não tentar fazer novamente, caso deseje informar o south que aquela migração já tenha sido realizada, possivelmente para corrigir algum problema, basta utilizar o comando:
python manage.py migrate --fake

Desta forma ele vai apagar as migrações contidas nos schemas gerados e colocar no banco como realizada, sem fazer nenhuma alteração no banco.