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!

quarta-feira, 20 de abril de 2016

Como esconder alguns registros do changelist do admin do Django



A pergunta é simples: Pra que eu um dia iria precisar esconder alguns registros do change list, se já estou no admin como superuser?

Bom, imagine que seu cliente quer o acesso ao admin para gerenciar os conteúdos e também acesso a alguma seção do projeto que o login é necessário.

Quão surpreso você ficaria se descobrisse, que aquele seu cadastro de teste onde vc conseguia entrar para ajudar, testar e acompanhar o andamento do projeto fosse removido?

Isso, apesar de ridículo, não é de todo o impossível, e foi por passar por algo semelhante que escrevo este post.


Para ocultar os registros de uma determinada classe, basta  sobrescrever o método get_queryset do admin daquela classe no admin.py:

class CadastroAdmin(admin.ModelAdmin):
 form = CadastroForm
 search_fields = ('nome',)
 list_display = ('nome', 'email', 'unidade','ativo',)
 list_filter = ['ativo','unidade']
 list_editable = ['ativo',]
 exclude = ('user',)
 save_on_top = True


 def get_queryset(self, request):
  qs = super(CadastroAdmin, self).get_queryset(request)
  if request.user.is_superuser:
   return qs
  return qs.exclude(id__in=[13,14,15])

admin.site.register(Cadastro, CadastroAdmin)

No exemplo acima, quando o usuário logado for superuser do admin, este verá todos os registros, do contrário, a queryset excluirá dos resultados os cadastros com ids 13, 14 e 15.

Com pequenos ajustes, este método tornar bastante útil para evitar dedos inquietos clicando onde não devem.


hasta!

sexta-feira, 8 de abril de 2016

SyntaxError: expected expression, got '<' /admin/jsi18n/ (line 1) interpolate is not defined

SyntaxError: expected expression, got '<'  <!DOCTYPE html> /admin/jsi18n/ (line 1) 
interpolate is not defined

Esse erro apareceu quando fiz a utilização do SelectFilter2 para um form no front.

Ele é responsável pela ferramenta de filter_horizontal / filter_vertical do admin, e deveria ser exibido assim:




E com o erro era exibido assim:





Para resolver esse problema:


Adicione no seu urls.py:
...
url(r'^jsi18n/$', 'django.views.i18n.javascript_catalog'),
...


E no seu template que for utilzar o widget:

<script type="text/javascript" src="/jsi18n/" > </script>