..
.. META INFORMATION OF TRANSLATION
..
.. $TranslationStatus: Done, waiting for revision $
.. $OriginalRevision: 11268 $
.. $TranslationAuthors: Robson Mendonça $
..
.. INFO OF THIS FILE (DO NOT EDIT! UPDATED BY SUBVERSION)
..
.. $HeadURL: http://django-l10n-portuguese.googlecode.com/svn/branches/docs-1.0.X/ref/contrib/admin.txt $
.. $LastChangedRevision: 584 $
.. $LastChangedBy: robsonmwoc $
.. $LastChangedDate: 2009-10-06 21:58:04 -0300 (Tue, 06 Oct 2009) $
..
.. _ref-contrib-admin:
======================
O site admin do Django
======================
.. module:: django.contrib.admin
:synopsis: O site de administração do Django.
.. currentmodule:: django.contrib.admin
Uma das mais poderosas partes do Django é a inteface de administração
automática. Ela lê os metadados de seu model para fornecer uma inteface poderosa
e pronta para produção que produtores de conteúdo podem imediatamente usar para
começar a adicionar conteúdos ao site. Neste documento, nós discutimos como
ativar, usar e personalizar a interface de administração do Django.
.. admonition:: Nota
O site admin foi significantemente refatorado desde a versão 0.96. Este
documento descreve a versão mais nova do site admin, que permite
customizações mais ricas. Se você acompanha o desenvolvimento do Django em
si, você pode ter ouvido isso descrito como "newforms-admin."
Visão geral
===========
Há cinco passos para ativar o site admin do Django:
1. Adicione ``django.contrib.admin`` no seu ``INSTALLED_APPS``.
2. Determine quais models de aplicações devem ser editados pela interface
admin.
3. Para cada um destes models, opicionalmente, crie uma classe
``ModelAdmin`` que encapsula as funcionalidades customizadas do admin e
opções para este model particular.
4. Instancie um ``AdminSite`` e o informe sobre cada um de seus models e
classes ``ModelAdmin``.
5. Ligue a instância ``AdminSite`` ao seu URLconf.
.. seealso::
Para informações sobre como servir arquivos de mídia (imagens, JavaScript, e
CSS) associado ao admin em produção, veja :ref:`serving-media-files`.
Objetos ``ModelAdmin``
======================
.. class:: ModelAdmin
A classe ``ModelAdmin`` é a representação de um model na interface de
administração. Este são armazenados num arquivo chamado ``admin.py`` na sua
aplicação. Vamos dar uma olhada num exemplo muito simples de ``ModelAdmin``::
from django.contrib import admin
from myproject.myapp.models import Author
class AuthorAdmin(admin.ModelAdmin):
pass
admin.site.register(Author, AuthorAdmin)
.. admonition:: Você precisa de um objeto ``ModelAdmin`` sempre?
No exemplo anterior, a classe ``ModelAdmin`` não define quaisquer valores
personalizados (ainda). Como um resultado, a interface admin padrão será
fornecida. Se você estiver feliz com a interface admin padrão, você não
precisa definir um objeto ``ModelAdmin`` sempre -- você poder registrar a
classe model sem fornecer uma descrição do ``ModelAdmin``. O exemplo
anterior poderia ser simplicado para::
from django.contrib import admin
from myproject.myapp.models import Author
admin.site.register(Author)
Opções ``ModelAdmin``
---------------------
O ``ModelAdmin`` é muito flexível. Ele tem várias opções para lidar com
customização da interface. Todas as opções são definidas na subclasse
``ModelAdmin``::
class AuthorAdmin(admin.ModelAdmin):
date_hierarchy = 'pub_date'
.. attribute:: ModelAdmin.date_hierarchy
Sete o ``date_hierarchy`` com o nome de um ``DateField`` ou ``DateTimeField`` do
seu model, e a lista de dados incluirá uma navegação por data, utilizando o
campo informado.
Exemplo::
date_hierarchy = 'pub_date'
.. attribute:: ModelAdmin.form
Por padrão um ``ModelForm`` é dinamicamente criado para seu model. Ele é usado
para criar o formulário apresentado em ambas as páginas adicionar/editar. Você
pode facilmente fornecer seu próprio ``ModelForm`` para sobrescrever qualquer
comportamento de formulário nas páginas adicionar/editar.
Para um exemplo veja a seção `Adicionando validação personalizada ao admin`_.
.. attribute:: ModelAdmin.fieldsets
Sete ``fieldsets`` para controlar o layout das páginas "adicionar" e "editar" do
admin.
``fieldsets`` é uma lista de tuplas duplas, em que cada tupla dupla representa
um ``
`` sobre a página de formulário do admin. (Um ```` é
uma "seção" do formulário.)
As tuplas duplas estão no formato ``(name, field_options)``, onde ``name`` é uma
string representando o título do fieldset e ``field_options`` é um dicionário
com informações sobre o fieldset, incluíndo uma lista de campos para serem
mostrados nele.
Um exemplo completo, recebido do model ``django.contrib.flatpages.FlatPage``::
class FlatPageAdmin(admin.ModelAdmin):
fieldsets = (
(None, {
'fields': ('url', 'title', 'content', 'sites')
}),
('Advanced options', {
'classes': ('collapse',),
'fields': ('enable_comments', 'registration_required', 'template_name')
}),
)
Isso resulta numa página admin que parece com:
.. image:: _images/flatfiles_admin.png
Se o ``fieldsets`` não for fornecido, o Django mostrará o padrão de cada campo
que não for um ``AutoField`` e tenha um ``editable=True``, em um fieldset único,
na mesma ordem em que os campos foram definidos no model.
O dicionário ``field_optinos`` pode ter as seguintes chaves:
* ``fields``
Uma tupla com nomes de campos que serão mostrados no fieldset. Esta
chave é obrigatória.
Exemplo::
{
'fields': ('first_name', 'last_name', 'address', 'city', 'state'),
}
Para mostrar vários campos na mesma linha, envolva-os em suas próprias
tuplas. Neste exemplo, os campos ``first_name`` e ``last_name`` serão
mostrados na mesma linha::
{
'fields': (('first_name', 'last_name'), 'address', 'city', 'state'),
}
* ``classes``
Uma lista contendo classes extra de CSS para serem aplicadas ao
fieldset.
Exemplo::
{
'classes': ['wide', 'extrapretty'],
}
Duas classes úteis definidas por padrão no site admin são ``collapse``
e ``wide``. Os fieldsets com o estilo ``collapse`` serão inicialmente
encolhidos no admin e substituídos por um link "click para expandir".
Os fieldsets com o estilo ``wide`` ocuparão um espaço horizontal extra.
* ``description``
Uma string de texto opcional extra para ser mostrado no topo de cada
fieldset, abaixo do cabeçalho do fieldset.
Note que este valor *não* tem o HTML escapado quando é mostrado na
interface do admin. Isso permite você incluir HTML se assim desejar.
Aleternativamente você poder usar texto plano e
``django.utils.html.escape()`` para escapar quaisquer caracteres
especiais de HTML.
.. attribute:: ModelAdmin.fields
Use esta opção como uma alternativa ao ``fieldsets`` se o layout não importar
e se você deseja somente mostrar um sub-conjunto de campos disponíveis no
formulário. Por exemplo, você poderia definir uma versão mais simples do
formulário do admin para o model ``django.contrib.flatpages.FlatPage`` desta
forma::
class FlatPageAdmin(admin.ModelAdmin):
fields = ('url', 'title', 'content')
No exemplo acima, somente os campos 'url', 'title' e 'content' serão mostrados,
sequencialmente, no formulário.
.. admonition:: Nota
Estas opções ``fields`` não devem ser confundidas com a chave de dicionário
``fields`` que fica dentro da opção ``fieldsets``, como descrito na seção
anterior.
.. attribute:: ModelAdmin.exclude
Este atributo, se fornecido, deve ser uma lista com nomes de campos a se escluir
do formulário.
Por exemplo, vamos considerar o seguinte model::
class Author(models.Model):
name = models.CharField(max_length=100)
title = models.CharField(max_length=3)
birth_date = models.DateField(blank=True, null=True)
Se você deseja um formulário do model ``Author`` que inclui somente os campos
``name`` e ``title``, você poderia especificar ``fields`` ou ``exclude`` desta
forma::
class AuthorAdmin(admin.ModelAdmin):
fields = ('name', 'title')
class AuthorAdmin(admin.ModelAdmin):
exclude = ('birth_date',)
Assim o model Author somente terá três campos, ``name``, ``title``, e
``birth_date``, os formulários resultantes das declarações acima conterão
extamante os mesmos campos.
.. attribute:: ModelAdmin.filter_horizontal
Use a nifty unobtrusive JavaScript "filter" interface instead of the
usability-challenged ```` in the admin form. The value is a
list of fields that should be displayed as a horizontal filter interface. See
``filter_vertical`` to use a vertical interface.
.. attribute:: ModelAdmin.filter_vertical
O mesmo que ``filter_horizontal``, mas é um display vertical do filtro.
.. attribute:: ModelAdmin.list_display
Configure o ``list_display`` para controlar quais campos são mostrados na
listagem do admin.
Exemplo::
list_display = ('first_name', 'last_name')
Se você não seta ``list_display``, o site admin mostrará uma única coluna que
mostra o ``__unicode__()`` representando cada objeto.
Você tem quatro valores possível que podem ser usado no ``list_display``:
* Uma campo de model. Por exemplo::
class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name')
* Uma função que aceita um paramêtro para a instância do model. Por
exemplo::
def upper_case_name(obj):
return ("%s %s" % (obj.first_name, obj.last_name)).upper()
upper_case_name.short_description = 'Name'
class PersonAdmin(admin.ModelAdmin):
list_display = (upper_case_name,)
* Uma string representando um atributo no ``ModelAdmin``. Este se comporta
da mesma forma que a função acima. Por exemplo::
class PersonAdmin(admin.ModelAdmin):
list_display = ('upper_case_name',)
def upper_case_name(self, obj):
return ("%s %s" % (obj.first_name, obj.last_name)).upper()
upper_case_name.short_description = 'Name'
* Uma string representando um atributo no model. Este se comporta quase como
a função acima, a diferença é que o ``self`` neste contexto é a instância
do model. Aqui temos um exemplo completo::
class Person(models.Model):
name = models.CharField(max_length=50)
birthday = models.DateField()
def decade_born_in(self):
return self.birthday.strftime('%Y')[:3] + "0's"
decade_born_in.short_description = 'Birth decade'
class PersonAdmin(admin.ModelAdmin):
list_display = ('name', 'decade_born_in')
Uns poucos casos especiais para se tomar nota sobre o ``list_display``::
* Se o campo é um ``ForeignKey``, o Django mostrará o ``__unicode`__()`` do
objeto relacionado.
* Campos ``ManyToManyField`` não são suportados, pois poderiam implicar em
execução de consultas SQL em separado pra cada linha da tabela. Se você
deseja fazer isso de qualquer forma, dê ao seu model um método
personalizado, e adicione o nome desse método no ``list_display``. (Veja
abaixo para saber mais sobre métodos personalizados no ``list_display``.)
* Se o campo é um ``BooleanField`` ou ``NullBooleanField``, o Django
mostrará um belo ícone "on" ou "off" ao invés de ``True`` ou ``False``.
* Se a string fornecida é um método do model, ``ModelAdmin`` ou uma função,
o Django espacará o HTML da saída por padrão. Se você gostaria de não
escapar a saída do método, de ao método um atributo ``allow_tags`` cujo o
valor é ``True``.
Aqui temos um exemplo completo::
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
color_code = models.CharField(max_length=6)
def colored_name(self):
return '%s %s ' % (self.color_code, self.first_name, self.last_name)
colored_name.allow_tags = True
class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'colored_name')
* Se a string dada é um método do model, ``ModelAdmin`` ou uma função que
retorna True ou False o Django mostrará um belo ícone "on" ou "off" se
você der ao método um atributo ``boolean`` cujo o valor é ``True``.
Aqui temos um exemplo completo do model::
class Person(models.Model):
first_name = models.CharField(max_length=50)
birthday = models.DateField()
def born_in_fifties(self):
return self.birthday.strftime('%Y')[:3] == '195'
born_in_fifties.boolean = True
class PersonAdmin(admin.ModelAdmin):
list_display = ('name', 'born_in_fifties')
* Os métodos ``__str__()`` e ``__unicode__()`` não só são válidos no
``list_display`` como em qualquer outro método de model, então é
perfeitamente OK usar isso::
list_display = ('__unicode__', 'some_other_field')
* Normalmente, os elementos do ``list_display`` que não estão dentre os
campos do bancos de dados atual não podem ser usado em ordenamentos (pois
o Django não sabe como sortealos a nível de banco de dados).
Entretanto, se um elemento de um ``list_display`` representa um certo
campo do banco de dados, você pode indicar este fato configurando o
atributo ``admin_order_field`` do item.
Por exemplo::
class Person(models.Model):
first_name = models.CharField(max_length=50)
color_code = models.CharField(max_length=6)
def colored_first_name(self):
return '%s ' % (self.color_code, self.first_name)
colored_first_name.allow_tags = True
colored_first_name.admin_order_field = 'first_name'
class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'colored_first_name')
O exemplo acima dirá ao Django para ordenar o campo ``first_name`` quando
tentar sortear pelo ``colored_first_name`` no admin.
.. attribute:: ModelAdmin.list_display_links
Seta um ``list_display_links`` para controlar quais campos no ``list_display``
deveriam ser linkados à página de edição de um objeto.
Por padrão, a página de listagem linkará a primeira coluna -- o primeiro campo
especificado no ``list_display`` -- para a página de edição de cada item. Mas
``list_display_links`` permite você mudar quais colunas serão linkadas.
Configure ``list_display_links`` com uma lista de tuplas com nomes de campos (no
mesmo formato como ``list_display``) para linkar.
O ``list_display_links`` pode especificar um ou mais nomes de campos. Tantos
quanto os nomes dos campos que aparecerem no ``list_display``, o Django não se
preocupa com quantos campos (ou quão poucos) serão linkados. O único requisito
é: Se você usar ``list_display_links``, você deve definir ``list_display``.
Neste exemplo, os campos ``first_name`` e ``last_name`` serão linkados na página
de listagem::
class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'birthday')
list_display_links = ('first_name', 'last_name')
.. attribute:: ModelAdmin.list_filter
Configure o ``list_filter`` para ativar os filtros na barra à direita da
listagem do admin. Este deve ser uma lista de nomes de campos, e cada campo
especificado devem ser ``BooleanField``, ``CharField``, ``DateField``,
``DateTimeField``, ``IntegerField`` ou ``ForeignKey``.
Este exemplo, pêgo do model ``django.contrib.auth.models.User``, mostra como
ambos ``list_display`` e ``list_filter`` funcionam::
class UserAdmin(admin.ModelAdmin):
list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
list_filter = ('is_staff', 'is_superuser')
O código acima resulta numa página de listagem do admim que parece com este:
.. image:: _images/users_changelist.png
(Este exemplo tem um ``search_fields`` definido. Veja abaixo.)
.. attribute:: ModelAdmin.list_per_page
Configure o ``list_per_page`` para controlar quantos ítens devem aparecer em
cada página da paginação da listagem. Por padrão, é setado para ``100``.
.. attribute:: ModelAdmin.list_select_related
Configure ``list_select_related`` para dizer ao Django para usar
``select_related()`` na lista de objetos recebida na listagem do admin. Isso
pode poupar um monte de consultas no banco de dados.
O valor deve ser ``True`` ou ``False``. O padrão é ``False``.
Note que o Django usará ``select_related()``, indiferente desta configuração,
se um dos campos no ``list_display`` for um ``ForeignKey``.
Para mais sobre ``select_related()``, veja
:ref:`a documentação do select_related() `.
.. attribute:: ModelAdmin.inlines
Veja objetos ``InlineModelAdmin`` abaixo.
.. attribute:: ModelAdmin.ordering
Configure ``ordering`` para especificar como os objetos na listagem do admin
devem ser ordenados. Este deve ser uma lista de tuplas no mesmo formato do
parâmetro ``ordering`` do model.
Se este não for fornecido, o Django admin usará o ordenamento padrão do model.
.. admonition:: Nota
O Django somente honra o primeiro elemento na lista/tupla; qualquer outro
será ignorado.
.. attribute:: ModelAdmin.prepopulated_fields
Configure ``prepopulated_fields`` com um mapeamento num dicionário com os campos
que devem ser pré-populados a partir de outro campo::
class ArticleAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}
Quando configurado, os campos dados usaram um pouco de JavaScript para popular
os campos atribuídos. O principal uso para esta funcionalidade é a de
automaticamente gerar um valor para campos ``SlugField`` a partir de um ou mais
campos. O valor gerado é produzido concatenando os valores do campo originário,
e então transformando este resultado num slug válido (e.g. substituíndo barras
por espaços).
O ``prepopulated_fields`` não aceita campos ``DateTimeField``, ``ForeignKey``,
nem ``ManyToManyField``.
.. attribute:: ModelAdmin.radio_fields
Por padrão, o admin do Django usa uma interface com select-box () para
campos que são ``ForeignKey`` ou que tem ``choices`` configurado. Se um campo é
apresentado no ``radio_fields``, o Django usará uma interface com radio-button
ao invés. Assumindo que ``group`` é um ``ForeignKey`` no model ``Person``::
class PersonAdmin(admin.ModelAdmin):
radio_fields = {"group": admin.VERTICAL}
Você tem a escolha de usar ``HORIZONTAL`` ou ``VERTICAL`` do módulo
``django.contrib.admin``.
Não inclua um campo no ``radio_fields`` a menos que seja um ``ForeignKey`` ou
tenha ``choices`` setado.
.. attribute:: ModelAdmin.raw_id_fields
Por padrão, o admin do Django usa um select-box () para campos que são
``ForeignKey``. Algumas vezes você pode não desejar ficar sujeito a um overhead
ao selecionar todos as instâncias relacionadas num drop-down.
O ``raw_id_fields`` é uma lista de campos que você gostaria de mudar dentro de
um widget ``Input`` tanto para ``ForeignKey`` quanto ``ManyToManyField``::
class ArticleAdmin(admin.ModelAdmin):
raw_id_fields = ("newspaper",)
.. attribute:: ModelAdmin.save_as
Seta ``save_as`` para habilitar um "save as" no formulário de edição do admin.
Normalmente, objetos tem três opções de salve: "Salvar", "Salvar e continuar
editando" e "Salvar e adicionar outro". Se ``save_as`` for ``True``, o "Salvar e
adicionar outro" será substituído por um botão "Salvar como".
.. admonition:: Nota do tradutor
Se você não estiver utilizando uma versão do Django traduzida, os botões
"Salvar e continuar editando", "Salvar", "Salvar e adicionar outro" e
"Salvar como", serão, respectivamente, "Save", "Save and continue editing",
"Save and add another" e "Save as".
"Salvar como" significa que o objeto será salvo como um novo objeto (com um novo
ID), ao invés de um objeto já existente.
Por padrão, ``save_as`` é setado como ``False``.
.. attribute:: ModelAdmin.save_on_top
Seta ``save_on_top`` para adicionar os botões de salvar no topo do formulário
de edição do admin.
Normalmente, os botões salvar aparecem somente na base do formulário. Se você
setar ``save_on_top``, os botões aparecerão em ambos os lugares, na base e no
topo.
Por padrão, ``save_on_top`` é setado como ``False``.
.. attribute:: ModelAdmin.search_fields
Configure ``search_fields`` para habilitar uma caixa de busca na página de
listagem do admin. Este deve ser configurado com uma lista de nomes de campos
que serão afetados pela busca, sempre que alguém submeter um texto por esta
caixa de texto.
Estes campos devem ser algum tipo de campo de texto, como ``CharField`` ou
``TextField``. Você pode também executar uma pesquisa relacionada a
``ForeignKey`` com a lookup API "siga" a notação::
search_fields = ['foreign_key__related_fieldname']
Quando alguém faz uma busca pelo admin, o Django divide a consulta em palavras e
retorna todos os objetos que contém cada uma das palavras, diferenciando
maiúsculas, onde pelo menos uma das palavras deve estar no ``search_fields``.
Por exemplo, se ``search_fields`` é setado para ``['first_name', 'last_name']``
e um usuário procura por ``john lennon``, o Django fará o equivalente a esta
clausula SQL ``WHERE``::
WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%')
AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')
Para buscas mais rápidas e/ou mais restritivas, prefixe o nome do campo com um
operador:
``^``
Combina com o início do campo. Por exemplo, se ``search_fields`` é setado
para ``['^first_name', '^last_name']`` e um usuário procurar por
``john lennon``, o Django fará o equivalente a clausula SQL ``WHERE``::
WHERE (first_name ILIKE 'john%' OR last_name ILIKE 'john%')
AND (first_name ILIKE 'lennon%' OR last_name ILIKE 'lennon%')
Esta consulta é mais eficiente que a normal ``'%john%'``, pois o banco de
dados somente precisa checar o início dos dados da coluna, ao invés de
procurar através de todo ele. Ainda mais, se a coluna tem um index nela,
alguns bancos de dados podem ser capazes de usar o index para esta consulta,
mesmo sendo uma consulta ``LIKE``.
``=``
Combina exatamente, não diferencia maiúsculas. Por exemplo, se
``search_fields`` for configurado para ``['=first_name', '=last_name']`` e
um usuário procura por ``john lennon``, o Django fará o equivalente a
clausula SQL ``WHERE``::
WHERE (first_name ILIKE 'john' OR last_name ILIKE 'john')
AND (first_name ILIKE 'lennon' OR last_name ILIKE 'lennon')
Note que a entrada da consulta é dividida nos espaços, então, seguindo este
exemplo, atualmente não é possível procurar por todos os dados em que
``first_name`` é exatamente ``'john winston'`` (contendo espaço).
``@``
Executa uma combinação full-text. Essa é como o método de procura padrão,
mas usa um index. Atualmente isso só está desponível para MySQL.
.. attribute:: ModelAdmin.change_list_template
Caminho para um template personalizado que será usado pelos objetos model na
visão de "listagem". Os templates podem sobrescrever ou extender os templates
de base do admin como descrito em `Sobrescrevendo Templates do Admin`_.
Se você não especificar este atributo, um template padrão é entregue com o
Django que fornece a aparência padrão do admin.
.. attribute:: ModelAdmin.change_form_template
Caminho para o template personalizado que será usado na visão de criação e
edição de um objeto model. Os templates podem sobrescrever ou extender os
templates de base do admin como descrito em
`Sobrescrevendo Templates do Admin`_.
Se você não especificar este atributo, um template padrão é entregue com o
Django que fornece a aparência padrão do admin.
.. attribute:: ModelAdmin.object_history_template
Caminho para um template que será usado na visão de histórico do objeto model.
Os templates podem sobrescrever ou extender os templates de base do admin como
descrito em `Sobrescrevendo Templates do Admin`_.
Se você não especificar este atributo, um template padrão é entregue com o
Django que fornece a aparência padrão do admin.
.. attribute:: ModelAdmin.delete_confirmation_template
Caminho para um template personalizado que será usado pela visão responsável por
mostrar a confirmação de exclusão de um ou mais objetos. Os templates podem
sobrescrever ou extender os templates de base do admin como descrito em
`Sobrescrevendo Templates do Admin`_.
Se você não especificar este atributo, um template padrão é entregue com o
Django que fornece a aparência padrão do admin.
.. _model-admin-methods:
Métodos do ``ModelAdmin``
-------------------------
.. method:: ModelAdmin.save_model(self, request, obj, form, change)
O método ``save_model`` recebe o ``HttpRequest``, uma intância do model, uma
instância de ``ModelForm`` e um valor booleano indicando se está adicionando ou
editando um objeto. Aqui você pode fazer quaisquer operações pré ou pós
salvamento.
Por exemplo, para atachar ``request.user`` ao objeto antes de salvá-lo::
class ArticleAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.user = request.user
obj.save()
.. method:: ModelAdmin.save_formset(self, request, form, formset, change)
O método ``save_formset`` recebe o ``HttpRequest``, a instância do ``ModelForm``
pai e um valor booleano que indica se está adicionando ou editando um objeto
pai.
Pro exemplo para atachar ``request.user`` a cada instância de formset de
mudança::
class ArticleAdmin(admin.ModelAdmin):
def save_formset(self, request, form, formset, change):
instances = formset.save(commit=False)
for instance in instances:
instance.user = request.user
instance.save()
formset.save_m2m()
Outros métodos
~~~~~~~~~~~~~~
.. method:: ModelAdmin.add_view(self, request, form_url='', extra_context=None)
Um view do Django para a página de inclusão de instância de model. Veja a nota
abaixo.
.. method:: ModelAdmin.change_view(self, request, object_id, extra_context=None)
Um view do Django para a página de edição de instância de model. Veja nota
abaixo.
.. method:: ModelAdmin.changelist_view(self, request, extra_context=None)
Um view do Django para página de listagem/ações de instância de model. Veja nota
abaixo.
.. method:: ModelAdmin.delete_view(self, request, object_id, extra_context=None)
Um view do Django para página de confirmação de exclusão de instância e model.
Veja nota abaixo.
.. method:: ModelAdmin.history_view(self, request, object_id, extra_context=None)
Um view do Django para a página que mostra o histórico de modificações de uma
instância de model.
Diferentemente dos métodos tipo hook do ``ModelAdmin`` detalhados na seção
anterior, estes cinco métodos são na verdade, projetados para serem invocados
como views do Django pelo URL dispatcher da aplicação admin que renderizam
páginas com instâncias de model para operações CRUD. Como resultado, a completa
sobrescrita destes métodos mudará o comportamento da aplicação admin.
Uma razão comum para sobrescrever estes métodos é para aumentar o contexto dos
dados que são fornecidos para o template que renderiza o view. No exemplo a
seguir, o view de edição é sobrescrito de modo que ao template renderizado é
fornecido alguns dados extras que caso contrário não estariam disponíveis::
class MyModelAdmin(admin.ModelAdmin):
# Um template para um view bastante personalizada:
change_form_template = 'admin/myapp/extras/openstreetmap_change_form.html'
def get_osm_info(self):
# ...
def change_view(self, request, object_id, extra_context=None):
my_context = {
'osm_data': self.get_osm_info(),
}
return super(MyModelAdmin, self).change_view(request, object_id,
extra_context=my_context)
Definições de mídia ``ModelAdmin``
----------------------------------
Tem vezes em que você gostaria de adicionar um pouco de CSS e/ou JavaScript aos
views adicionar/editar. Isso pode ser realizado usando uma classe interna Media
no seu ``ModelAdmin``::
class ArticleAdmin(admin.ModelAdmin):
class Media:
css = {
"all": ("my_styles.css",)
}
js = ("my_code.js",)
Tenha em mente que este será prefixado com ``MEDIA_URL``. A mesma regra se
aplica nas :ref:`regras de definições de mídia em formulários
`.
Adicionando validação personalizada ao admin
--------------------------------------------
Adicionando validação personalizada de dados no admin é bem simples. A interface
automática de administração reusa o :mod:`django.forms`, e a classe
``ModelAdmin`` tem a mesma abilidade de definir seu próprio formulário::
class ArticleAdmin(admin.ModelAdmin):
form = MyArticleAdminForm
O ``MyArticleAdminForm`` pode ser definido em qualquer lugar dentro de seu
caminho de import. Agora com seu form você pode adicionar sua própria validação
para qualquer campo::
class MyArticleAdminForm(forms.ModelForm):
class Meta:
model = Article
def clean_name(self):
# faça algo que valide seus dados
return self.cleaned_data["name"]
É importante usar um ``ModelForm`` aqui, caso contrário algo pode não funcionar.
Veja a documentação :ref:`forms ` em :ref:`valização
personalizada ` e, mais especificamente, o :ref:`notas de
validação de formulários ` para mais
informações.
.. _admin-inlines:
Objetos ``InlineModelAdmin``
============================
A interface admin tem a abilidade de editar models na mesma página de um model
pai. Este são chamados de inlines. Suponhamos que você tenha dois models::
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
author = models.ForeignKey(Author)
title = models.CharField(max_length=100)
Você pode editar os livros escritos por um autor na página do autor. Você pode
adicionar inlines ao seu model para especificá-los em um
``ModelAdmin.inlines``::
class BookInline(admin.TabularInline):
model = Book
class AuthorAdmin(admin.ModelAdmin):
inlines = [
BookInline,
]
O Django fornece duas subclasses ao ``InlineModelAdmin`` e elas são:
* ``TabularInline``
* ``StackedInline``
A diferença entre estas duas é meramente o template utilizado para
renderizá-las.
Opções ``InlineModelAdmin``
---------------------------
A classe ``InilneModelAdmin`` é uma subclasse de ``ModelAdmin`` de modo que ele
herda todas as mesmas funcionalidades assim como as suas próprias:
``model``
~~~~~~~~~
O model em que o inline é usado. Este é obrigatório.
``fk_name``
~~~~~~~~~~~
O nome da chave estrangeira no model. Na maioria dos casos este será tratado
de forma automática, mas ``fk_name`` deve ser especificada explicitamente se
houver mais de uma chave estrangeira para o mesmo model pai.
``formset``
~~~~~~~~~~~
O padrão para ``BaseInlineFormSet``. Usar seu próprio formset pode dar a você
muitas possibilidades de personalização. Inlines são embutidos a volta de
:ref:`model formsets `.
``form``
~~~~~~~~
O valor para ``form`` padrão para ``BaseModelForm``. Este é o que é passado
através do ``formset_factory`` quando está criando o formset para este inline.
``extra``
~~~~~~~~~
Este controla o número de formulários extra que um formset mostrará além dos
formulário inciais. Veja a :ref:`documentação dos formsets
` para mais informações.
``max_num``
~~~~~~~~~~~
Este controla o número máximo de formulários que serão mostrados num inline.
Este não é diretamente correlacionado ao número de objetos, mas pode ser se o
valor for pequeno o suficiente. Veja :ref:`model-formsets-max-num` para mais
informações.
``raw_id_fields``
~~~~~~~~~~~~~~~~~
Por padrão, o admin do Django usa um select-box () para campos que são
``ForeignKey``. Algumas vezes você pode não desejar ficar sujeito a um overhead
ao selecionar todos as instâncias relacionadas num drop-down.
O ``raw_id_fields`` é uma lista de campos que você gostaria de mudar dentro de
um widget ``Input`` tanto para ``ForeignKey`` quanto para ``ManuToManyField``::
class BookInline(admin.TabularInline):
model = Book
raw_id_fields = ("pages",)
``template``
~~~~~~~~~~~~
O template usado para renderizar o inline na página.
``verbose_name``
~~~~~~~~~~~~~~~~
Uma sobrescrita para ``verbose_name`` encontrado na classe interna ``Meta`` do
model.
``verbose_name_plural``
~~~~~~~~~~~~~~~~~~~~~~~
Uma sobrescrita para o ``verbose_name_plural`` encontrado na classe interna
``Meta`` do model.
Trabalhando com um model com duas ou mais chaves estrangeiras para o mesmo model pai
------------------------------------------------------------------------------------
Algumas vezes é possível haver mais de uma chave estrangeira para o mesmo model.
Vejamos esta instância de model::
class Friendship(models.Model):
to_person = models.ForeignKey(Person, related_name="friends")
from_person = models.ForeignKey(Person, related_name="from_friends")
Se você quiser mostrar um inline nas páginas adicionar/editar do admin para
``Person``, você precisa explicitamente definir a chave primária, tendo em vista
que ele não consegue definir automáticamente::
class FriendshipInline(admin.TabularInline):
model = Friendship
fk_name = "to_person"
class PersonAdmin(admin.ModelAdmin):
inlines = [
FriendshipInline,
]
Trabalhando com Models Intermediários Many-to-Many
--------------------------------------------------
Por padrão, os widgets do admin para relações muito-para-muitos serão mostrados
inlines não importando qual model contém a referência atual para o
``ManyToManyField``. No entanto, quando você especificar um model intermediário
usando o argumento ``through`` para um ``ManyToManyField``, o admin não mostrará
o widget por padrão. Isso porque cada instância de model intermediário requer
mais informações que poderiam ser mostradas num único widget, e o layout
requerido por vários widgets irão variar dependendo do model intermediário.
No entanto, nós ainda queremos ter a possibilidade de editar estar informações
inline. Felizmente, isso é fácil de fazer com admin models inline. Suponhamos
que temos os seguintes models::
class Person(models.Model):
name = models.CharField(max_length=128)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
class Membership(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
O primeiro passo em mostrar este model intermediário no admin é definir uma
classe inline para o model ``Membership``::
class MembershipInline(admin.TabularInline):
model = Membership
extra = 1
Este exemplo simples usa o valor padrão ``InlineModelAdmin`` para o model
``Membership``, e limita os formulários adicionais para um. Isso poderia ser
personalizado usando qualquer uma das opções disponíveis para classes
``InlineModelAdmin``.
Agora crie visões no admin para os models ``Person`` e ``Group``::
class PersonAdmin(admin.ModelAdmin):
inlines = (MembershipInline,)
class GroupAdmin(admin.ModelAdmin):
inlines = (MembershipInline,)
Finalmente, registre seus models ``Person`` e ``Group`` no site admin::
admin.site.register(Person, PersonAdmin)
admin.site.register(Group, GroupAdmin)
Agora seu site admin está configurado para editar objetos ``Membership`` tanto
da página de detalhes do ``Person`` quanto do ``Group``.
Usando relações genéricas como um inline
----------------------------------------
É possível usar um inline com objetos relacionados genericamente. Vamos dizer
que você tenha os seguintes models::
class Image(models.Model):
image = models.ImageField(upload_to="images")
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey("content_type", "object_id")
class Product(models.Model):
name = models.CharField(max_length=100)
Se você quer permitir a edição e criação de instâncias ``Image`` sobre
``Product`` você pode simplesmente usar ``GenericInlineModelAdmin`` fornecido
pelo ``django.contrib.contenttypes.generic``. No seu ``admin.py`` para esta
aplicação de exemplo::
from django.contrib import admin
from django.contrib.contenttypes import generic
from myproject.myapp.models import Image, Product
class ImageInline(generic.GenericTabularInline):
model = Image
class ProductAdmin(admin.ModelAdmin):
inlines = [
ImageInline,
]
admin.site.register(Product, ProductAdmin)
O ``django.contrib.contenttypes.generic`` fornece ambos um
``GenericTabularInline`` e ``GenericStackedInline`` e se comporta como qualquer
outro inline. Veja a :ref:`documentação do contenttypes
` para informações mais específicas.
Sobrescrevendo Templates do Admin
=================================
É relativamente fácil sobrescrever a maior parte dos templates que o módulo de
admin usa para gerar as várias páginas de um site admin. Você pode sobrescrever
somente algumas partes desses templates para uma app específica, ou um model
específico.
Configurando os diretórios de template do admin do seu projeto
--------------------------------------------------------------
Os arquivos de template do admin estão localizados no diretório
``contrib/admin/templates/admin``.
A fim de sobrescrever um ou mais deles, primeiro crie um diretório ``admin`` no
diretórios de templates do seu projeto. Este pode ser qualquer um dos diretórios
que você especificou no ``TEMPLATE_DIRS``.
Dentro deste diretório ``admin``, crie sub-diretórios com o nome de suas apps.
Dentro destes sub-diretórios crie sub-diretórios com o nome de seus models.
Perceba, que a aplicação admin procura por nomes de diretórios em minúsculo,
então esteja certo do nome deles está todo em minúsculo, caso você esteja
rodando sua aplicação num sistemas de arquivo case-sensitive.
Para sobrescrever um template do admin para uma app específica, copie e edite o
template do diretório ``django/contrib/admin/templates/admin``, e salve-o num
dos diretórios criados a pouco.
Por exemplo, se nós procurarmos adicionar uma ferramenta na visão de listagem
para todos os models de uma aplicação chamada ``my_app``, nós copiariámos
``contrib/admin/templates/admin/change_list.html`` para o diretório
``templates/admin/my_app/`` de seu projeto, e fariámos as mudanças necessárias.
Caso desejássemos adicionar uma ferramenta na visão de listagem somente para um
model específico chamado 'Page', nós poderiámos copiar aquele mesmo arquivo para
o diretório ``templates/admin/my_app/page`` de seu projeto.
Sobrescrever vs. substituir um template do admin
------------------------------------------------
Por causa do design modular dos templates do admin, geralmente é necessário, mas
nem sempre aconselhável, substituir todo um template. É quase semper melhor
sobrescrever somente a seção do template que precisa ser mudada.
Para continuar o exemplo acima, nós queremos adicionar um novo link próximo ao
``History`` para o model ``Page``. Depois de olhar no ``change_form.html`` nós
determinamos que somente precisamos sobrescrever o bloco ``object-tools``.
Assim, aqui está o novo ``change_form.html`` :
.. code-block:: html+django
{% extends "admin/change_form.html" %}
{% load i18n %}
{% block object-tools %}
{% if change %}{% if not is_popup %}
{% endif %}{% endif %}
{% endblock %}
E era isso! Se nós colocarmos este arquivo no diretório
``templates/admin/my_app``, nosso link apareceria em todos os formulários de
edição dos models.
Templates que podem ser sobrescritos por uma app ou model
---------------------------------------------------------
Nem todo template em ``contrib/admin/templates/admin`` pode ser sobrescrito por
app ou por model. Os seguintes podem:
* ``change_form.html``
* ``change_list.html``
* ``delete_confirmation.html``
* ``object_history.html``
Para a maioria dos templates que não são sobrescritos desta forma, você pode
ainda sobrescrevê-los pra o seu projeto inteiro. É só colocar uma nova versão
no seu diretório ``templates/admin``. Este é particularmente útil para criar
páginas de erro 404 e 500.
.. note::
Alguns dos templates do admin, como o ``change_list_request.html`` são
usados para renderizar inclusion tags personalizadas. Estas podem ser
sobrescritas, mas em alguns casos provavelmente é melhor você criar sua
própria versão da tag em questão e dá-lhe um nome diferente. Desta forma
você pode usá-la seletivamente.
Template raiz e de login
------------------------
Se você deseja mudar o template index ou de login, seria melhor você criar sua
própria instância de ``AdminSite`` (veja abaixo), e mudar as propriedades
:attr:`AdminSite.index_template` ou :attr:`AdminSite.login_template`.
Objetos ``AdminSite``
=====================
Um site de administração do Django é representado por uma instância do
``django.contrib.admin.sites.AdminSite``; por padrão, uma instância desta classe
é criada como ``django.contrib.admin.site`` e você pode registrar seus models
e instâncias do ``modelAdmin`` nele.
Se você gostaria de configurar de setar sua própria interface de administração
com comportamentos personalizados, contudo, você é livre para extender o
``AdminSite`` e sobrescrever ou adicionar qualquer coisa que queira. Então,
simplesmente crie uma instância de sua classe extendida do ``AdminSite`` (da
mesma forma como você instancia qualquer outra classe Python), e registre seus
models e subclasses de ``ModelAdmin`` com ele ao invés de usar o padrão.
Atributos do ``AdminSite``
--------------------------
.. attribute:: AdminSite.index_template
Caminho para um template personalizado que será usado pela página principal do
site de administração. Os templates podem sobrescrever ou extender os templates
base do admin como descrito em `Sobrescrevendo Templates do Admin`_.
.. attribute:: AdminSite.login_template
Caminho para um templates personalizado que será usado pela página de login do
site admin. Os templates podem sobrescrever ou extender os templates base do
admin como descrito em `Sobrescrevendo Templates do Admin`_.
Vinculando instâncias do ``AdminSite`` ao seu URLconf
-----------------------------------------------------
O último passo ao configurar o admin do Django é vincular o sua instância
``AdminSite`` dentro do seu URLconf. Faça isso apontando uma certa URL para o
método ``AdminSite.urls``.
Neste exemplo, nós registramos a instância padrão ``AdminSite`` do
``django.contrib.admin.site`` na URL ``/admin`` ::
# urls.py
from django.conf.urls.defaults import *
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
('^admin/(.*)', admin.site.root),
)
Acima nós usamos ``admin.autodiscover()`` para automaticamente carregar os
módulos admin.py do ``INSTALLED_APPS``.
Neste exemplo, nós registramos a instância do ``AdminSite``
``myproject.admin.admin_site`` na URL ``/myadmin/`` ::
# urls.py
from django.conf.urls.defaults import *
from myproject.admin import admin_site
urlpatterns = patterns('',
('^myadmin/(.*)', admin_site.root),
)
Realmente não há necessidade de usar o autodiscover quando estiver usando sua
própria instância do ``AdminSite``, tendo em vista que você provavelmente já
tenha importado todos os seus módulos admin.py das aplicações no seu módulo
``myproject.admin``.
Note que a expressão regular no URLpattern *deve* agrupar tudo que vier após
a raiz da URL -- por isso o ``(.*)`` nestes exemplos.
Vários sites admin no mesmo URLconf
-----------------------------------
É fácil criar várias instâncias de admin no mesmo site feito em Django. É só
criar várias instâncias do ``AdminSite`` e colocá-los em URLs diferentes.
Neste exemplo, as URLs ``/baisc-admin/`` e ``/advanced-admin/`` realçam versões
separadas do site admin -- usando as instâncias do ``AdminSite``
``myproject.admin.basic_site`` e ``myproject.admin.advanced_site``,
respectivamente::
# urls.py
from django.conf.urls.defaults import *
from myproject.admin import basic_site, advanced_site
urlpatterns = patterns('',
('^basic-admin/(.*)', basic_site.root),
('^advanced-admin/(.*)', advanced_site.root),
)