Criando uma primeira aplicação com Django e mysql

Personalizando o formulário de administração do django

https://docs.djangoproject.com/pt-br/1.11/intro/tutorial07/

Para baixar o código como está até agora, acesse o meu github no link abaixo:
https://github.com/toticavalcanti/django_course/tree/form_customize

Personalizando formulario de administração django

Personalizando formulario de administração django

Continuando de onde paramos na aula 23, seguindo o restante da parte 7 do tutorial da documentação oficial do Django.

Há um pequeno problema.

Há um monte de espaço na tela para exibir apenas três objetos Choices relacionadas a serem inseridas.

Por essa razão, o Django oferece uma maneira alternativa para exibir cada objeto relacionado em uma única linha, você só precisa alterar a declaração ChoiceInline em polls/admin.py, para que seja:


class ChoiceInline(admin.TabularInline):
    #.....

Com o TabularInline (em vez de StackedInline), os objetos relacionados são exibidos de uma maneira mais compacta, formatada em tabela.

Adicionar question TabularInline

Adicionar question com TabularInline

Observe que há uma coluna extra “Apagar?” que permite a remoção de linhas adicionadas usando o botão “Add Another Choice” e linhas que já foram salvas.

Agora que a página de administração da Question está bonita, vamos fazer algumas melhorias na página “change list” – aquela que exibe todas as enquetes do sistema.

Ela está assim agora:

Listagem das questions

Listagem das questions

Por padrão, o Django mostra o str() de cada objeto. Mas algumas vezes seria mais útil se pudéssemos mostrar campos individuais.

Para fazer isso, use a opção list_display, que é uma tupla de nomes de campos a serem exibidos, como colunas, na lista de mudança dos objetos.

polls/admin.py


from django.contrib import admin
from .models import Choice, Question

class ChoiceInline(admin.TabularInline):
    model = Choice
    extra = 3

class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
    ]
    inlines = [ChoiceInline]
    list_display = ('question_text', 'pub_date')
admin.site.register(Question, QuestionAdmin)

Agora ficou assim:

Listagem das questions com list display

Listagem das questions com list display

Vamos modificar de novo essa mesma linha do admin.py para incluir o método was_published_recently() da parte 2 do tutorial.

polls/admin.py


from django.contrib import admin
from .models import Choice, Question
class ChoiceInline(admin.TabularInline):
    model = Choice
    extra = 3
class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
    ]
    inlines = [ChoiceInline]
    list_display = ('question_text', 'pub_date', 'was_published_recently')
admin.site.register(Question, QuestionAdmin)

Agora tá assim:

Listagem das questions com was_published_recently

Listagem das questions com was_published_recently

Você pode clicar no cabeçalho da coluna para ordená-las por estes valores – exceto no caso do was_published_recently, porque a ordenação pelo resultado de um método arbitrário não é suportada.

Também note que o cabeçalho da coluna para was_published_recently é, por padrão, o nome do método (com underscores substituídos por espaços), e que cada linha contem a representação da saída.

Você pode melhorar isso adicionando ao método (em polls/models.py) alguns atributos, como segue:

polls/models.py


class Question(models.Model):

# ...

def was_published_recently(self):

    now = timezone.now()

    return now - datetime.timedelta(days=1) <= self.pub_date <= now

was_published_recently.admin_order_field = 'pub_date'

was_published_recently.boolean = True

was_published_recently.short_description = 'Published recently?'

Agora tá assim:

Listagem das com questions_was_published_recently modificado

Listagem das questions com questions_was_published_recently modificado

Adicionaremos agora no polls/admin.py, embaixo de:

list_display = ('question_text', 'pub_date', 'was_published_recently’)

Vamos adicionar:

list_filter = ['pub_date']

polls/admin.py


from django.contrib import admin
from .models import Choice, Question

class ChoiceInline(admin.TabularInline):
    model = Choice
    extra = 3

class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
    ]
    inlines = [ChoiceInline]
    list_display = ('question_text', 'pub_date', 'was_published_recently')
    list_filter = ['pub_date']
admin.site.register(Question, QuestionAdmin)

Adicionar question com três campos

Adicionar question com três campos

Listagem das questions side bar

Listagem das questions side bar

O tipo do filtro apresentado depende do tipo do campo pelo qual você está filtrando. Por conta de pub_date ser uma instância da classe DateTimeField, o Django consegue deduzir que os filtros apropriados são: “Qualquer data”, “Hoje”, “Últimos 7 dias”, “Esse mês”, “Esse ano”.

Isso está ficando bom. Vamos adicionar capacidade de pesquisa:

Adicionaremos agora no polls/admin.py, embaixo de:

list_filter = ['pub_date']

Vamos adicionar:

search_fields = ['question_text']

Isso adiciona um campo de pesquisa ao topo da lista de edição. Quando alguém informa termos de pesquisa, o Django irá pesquisar o campo question_text.

Você pode usar quantos campos quiser – entretanto, por ele usar uma consulta LIKE internamente, limitar o número de campos de pesquisa a um número razoável, será mais fácil para o seu banco de dados para fazer pesquisas.

Agora é também uma boa hora para observar que a página de edição fornece uma paginação.

O padrão é mostrar 100 itens por página. Paginação da página de edição, campos de pesquisa, filters, hierarquia por data e ordenação por cabeçalho de coluna, todos trabalham em sincronia como deveriam.

Obviamente, ter “Django administration” no topo de cada página de administração é ridículo. Isso é só um texto de exemplo.

É fácil de editar, no entanto, usando o sistema de templates do Django. A página de administração do Django é feita com o próprio Django e conseqüentemente sua interface usa o sistema de templates nativo do Django.

Criar um diretório templates no diretório do seu projeto (aquela que contém manage.py). Os modelos podem viver em qualquer lugar em seu sistema de arquivos que o Django possa acessar.

No entanto, manter seus templates dentro do projeto é uma boa convenção a seguir.

Abra seu arquivo de configurações (mysite/settings.py, lembre-se) e adicione uma opção DIRS. na configuração TEMPLATES setting:

mysite/settings.py


TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

DIRS é uma lista de diretórios de arquivos que serão checados quando o Django carregar seus templates, ou seja, caminhos de busca.

Organizando templates

Assim como arquivos estáticos, podemos ter todos os nossos templates juntos, em um grande diretório de templates, isso irá funcionar perfeitamente bem. Porém, os templates que pertencem a uma aplicação em particular devem ser mantidos no diretório de templates daquela aplicação (ex. polls/templates).

Agora crie um diretório template dentro de mysite, no nível do arquivo manage.py e dentro dela crie uma subpasta chamada admin, e copie o template admin/base_site.html de dentro do diretório padrão do site de administração do Django (django/contrib/admin/templates) para dentro deste diretório mysite_project/mysite/template/admin/base_site.html.

Onde estão os arquivos de código-fonte do Django?

Se você tiver dificuldade em encontrar onde os arquivos do Django estão localizados em seu sistema, execute o seguinte comando:

python -c "import django; print(django.__path__)" </code

Então, apenas edite o arquivo e substitua {{site_header|default:_(‘Django administration’) }} (incluindo as chaves) com nome do seu próprio site como desejar. Você deve acabar com uma secção de código como:


{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1>
{% endblock %}

Nós usamos esta abordagem para ensinar-lhe como substituir templates. Em um projeto real, você provavelmente usaria o atributo django.contrib.admin.AdminSite.site_header para fazer mais facilmente essa personalização em particular.

Esse template contém uma série de textos como {% block branding %} e {{ tittle }}. As tags {% e {{ fazem parte da linguagem de templates do Django.

Quando o Django renderiza o template “admin/base_site.html“, o seu conteúdo é processado por essa linguagem de templates para produzir a página HTML final, assim como vimos na parte 3 do tutorial.

Note que qualquer template padrão do site de administração pode ser sobrescrito. Para sobrescrever um template, apenas faça a mesma coisa que você fez com base_site.html – copie ele do diretório padrão para o seu próprio diretório, e faça as mudanças.

Leitores astutos irão se perguntar: Mas se DIRS estava vazio por padrão, como o Django pôde encontrar o diretório padrão dos templates do site de administração?

A resposta é, Desde que APP_DIRS seja True, o Django irá automaticamente procurar por um subdiretório templates/ dentro de cada pacote de aplicação, para usar como fallback(Não esqueça que django.contrib.admin é uma aplicação).

Nossa aplicação polls não é muito complexa e não precisa de templates personalizados para o site de administração.

Mas se ela crescer e ficar mais sofisticada, será necessária a modificação dos templates padrão de administração do Django para algumas de suas funcionalidades, seria mais sensato modificar os templates da aplicação, e não os do projeto.

Dessa forma, você poderia incluir a aplicação de enquete em qualquer novo projeto e ter a certeza que iria encontrar os modelos personalizados que você precisa.

De maneira similar, você pode querer personalizar a aparência da página inicial do site de administração do Django.

Por padrão, ele exibe todas as aplicações em INSTALLED_APPS, que estão registrados na aplicação de administração, em ordem alfabética. E você pode querer fazer alterações significativas no layout.

Além do que, a página inicial é provavelmente a página mais importante da página de administração, e deve ser fácil de usar.

O template para personalizar é admin/index.html. (Faça o mesmo que admin/base_site.html que fizemos anteriormente – copie ele do diretório padrão para o seu diretório de template personalizado).

Edite o arquivo e você verá que ele usa uma variável de template chamada app_list.

Esta variável contém cada app instalada no Django.

Ao invés de usar isto, você pode criar links hard-coded para páginas do admin específicas em qualquer forma que você achar melhor.

E agora?

O tutorial do iniciante em Django termina aqui.

Entretanto, você pode querer verificar alguns indicadores para onde seguir partindo daqui.

Se você é familiar ao sistema de empacotamento Python e está interessado em como tornar a polls em uma “app reusável”, veja o tutorial avançado: como escrever apps reusáveis.

Para baixar o código como está até agora, acesse o meu github no link abaixo:
https://github.com/toticavalcanti/django_course/tree/form_customize

AULA  23

AULA  25

Todas as Aulas da App Polls

Página Principal

Obrigado

Até a próxima

Aula 24 – Formulário de administração do Django – Continuação

About The Author
-

2 Comentários

  • Hamilton
    Reply

    Boa noite.
    Ao fazer a mudança no arquivo settings.py na chave ‘DIRS’, o servidor cai e acusa um erro informando que o nome ‘os’ não foi definido.
    Como posso resolver isso?

    • toticavalcanti
      Reply

      Opa Hamilton
      O erro diz que ‘os’ não foi definido.
      Dá uma olhada no início do settings.py e vê se você tá importando o os:
      import os

      Caso não resolva, sugiro você entrar no link do código no meu github, e copiar o código e colar aí no seu.
      Qualquer coisa, fala aí.
      \o/ 😉

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>