.. .. META INFORMATION OF TRANSLATION .. .. $TranslationStatus: Done, waiting for revision $ .. $OriginalRevision: 11298 $ .. $TranslationAuthors: Luiz Fernando Barbosa Vital, 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/topics/http/urls.txt $ .. $LastChangedRevision: 516 $ .. $LastChangedBy: robsonmwoc $ .. $LastChangedDate: 2009-08-01 22:32:34 -0300 (Sat, 01 Aug 2009) $ .. .. _topics-http-urls: ============== URL dispatcher ============== .. module:: django.core.urlresolvers Um esquema de URLs limpo e elegante é um detalhe importante numa aplicação Web de qualidade. O Django permite que você defina as URLs da maneira que quiser, sem limitações impostas pelo framework. Não são necessários ``.php``, ``.cgi`` ou outras coisas sem o menor sentido como ``0,2097,1-1-1928,00``. Veja `Cool URIs don't change`_, pelo criador da World Wide Web Tim Berners-Lee, para ter excelentes argumentos do porquê as URLs devem ser limpas e facilmente utilizáveis. .. _Cool URIs don't change: http://www.w3.org/Provider/Style/URI Visão geral =========== Para definir URLs para uma aplicação, você cria um módulo Python informalmente chamado de **URLconf** (URL configuration). Este módulo é Python puro e é um mapeamento simples entre padrões de URL (na forma de expressões regulares simples) para funções Python de callback (suas views). Este mapeamento pode ser tão extenso ou curto quanto necessário. Ele pode referenciar outros mapeamentos. E, por ser código Python puro, pode ser construído dinamicamente. .. _how-django-processes-a-request: Como o Django processa uma requisição ===================================== Quando um usuário requisita uma página de nosso site em Django, este é o algoritmo que o sistema segue para determinar qual código Python irá executar: 1. O Django determina o módulo URLconf inicial a ser usado. Normalmente, este é o valor de configuração do ``ROOT_URLCONF`` no arquivo settings, mas se o objeto ``HttpRequest`` de entrada tem um atributo chamado ``urlconf``, esse valor será utilizado no lugar da configuração ``ROOT_URLCONF``. 2. O Django carrega o módulo Python em questão e procura a variável ``urlpatterns``. Esta deve ser uma lista Python, no formato retornado pela função ``django.conf.urls.defaults.patterns()``. 3. O Django percorre cada padrão de URL, ordenadamente, e pára no primeiro padrão em que exista uma correspondência com a URL requisitada. 4. Uma vez que uma das expressões regulares corresponda, o Django importa e chama a view associada, que é uma simples função Python. Um :class:`~django.http.HttpRequest` é sempre passado como primeiro argumento da view e qualquer outro valor capturado pela expressão regular é passado como argumento adicional. Exemplo ======= Aqui está um URLconf de exemplo:: from django.conf.urls.defaults import * urlpatterns = patterns('', (r'^articles/2003/$', 'news.views.special_case_2003'), (r'^articles/(\d{4})/$', 'news.views.year_archive'), (r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'), (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'), ) Notas: * ``from django.conf.urls.defaults import *`` disponibiliza a função ``patterns()``. * Para capturar um valor da URL, simplesmente coloque parênteses em volta dele. * Não é necessário adicionar uma barra no início, porque toda URL tem isso. Por exemplo, o correto é ``^articles``, e não ``^/articles``. * O ``'r'`` na frente de cada string de expressão regular é opcional, mas recomendado. Ele diz ao Python que o conteúdo de uma string deve levar em conta caracteres como ``'\'`` literalmente em vez de interpretá-los como um caractere especial. Veja `a explicação do Dive Into Python`_. Requisições de exemplo: * Uma requisição para ``/articles/2005/03/`` corresponde ao terceiro elemento da lista. O Django então chama a função ``news.views.month_archive(request, '2005', '03')``. * ``/articles/2005/3/`` não corresponde a nenhum padrão, porque o terceiro elemento da lista requer dois dígitos para o mês. * ``/articles/2003/`` corresponde ao primeiro elemento da lista, e não ao segundo, porque os padrões são testados seguindo a ordem da lista, portanto o primeiro elemento é o primeiro a ser testado. Esteja à vontade para explorar a ordem das regras para inserir casos especiais como este. * ``/articles/2003`` não corresponde a nenhum destes padrões, pois cada padrão exige que a URL termine com uma barra. * ``/articles/2003/03/3/`` corresponde ao último padrão. O Django chama a função ``news.views.article_detail(request, '2003', '03', '3')``. .. _a explicação do Dive Into Python: http://diveintopython.org/regular_expressions/street_addresses.html#re.matching.2.3 Grupos nomeados =============== O exemplo acima usou grupos de expressões regulares simples e *não-nomeados* (usando parênteses) para capturar pedaços da URL e passá-los como argumentos *posicionais* para a view. Em um uso mais avançado, é possível utilizar grupos *nomeados* de expressões regulares para capturar pedaços de URL e passá-los como argumentos *nomeados* para a view. Em expressões regulares Python, a sintaxe para grupos nomeados é ``(?Ppadrão)``, onde ``nome`` é o nome do grupo e ``padrão`` é algum padrão a ser correspondido. Segue o URLconf do exemplo acima, reescrita para utilizar grupos nomeados:: urlpatterns = patterns('', (r'^articles/2003/$', 'news.views.special_case_2003'), (r'^articles/(?P\d{4})/$', 'news.views.year_archive'), (r'^articles/(?P\d{4})/(?P\d{2})/$', 'news.views.month_archive'), (r'^articles/(?P\d{4})/(?P\d{2})/(?P\d+)/$', 'news.views.article_detail'), ) Este exemplo faz exatamente a mesma coisa que o anterior, com uma pequena diferença: Os valores capturados são passados para as funções de view como argumentos nomeados em vez de argumentos posicionais. Por exemplo: * Uma requisição para ``/articles/2005/03/`` chama a função ``news.views.month_archive(request, year='2005', month='03')``, em vez de ``news.views.month_archive(request, '2005', '03')``. * Uma requisição para ``/articles/2003/03/3/`` chama a função ``news.views.article_detail(request, year='2003', month='03', day='3')``. Na prática, isso significa que seus URLconfs são um pouco mais explícitos e menos propensos a bugs de ordem de argumentos -- e você pode reordenar os argumentos nas definições de função de view. Obviamente, estes benefícios são obtidos ao custo da brevidade; alguns desenvolvedores acham a sintaxe de grupos nomeados feia e muito prolixa. O algoritmo de correspondência/agrupamento ------------------------------------------ Eis o algoritmo que o parser URLconf segue, no que diz respeito a grupos nomeados contra grupos não-nomeados em uma expressão regular: Se existe algum argumento nomeado, ele será utilizado, ignorando argumentos não-nomeados. Caso contrário, ele passará todos os argumentos não-nomeados como argumentos posicionais. Em ambos os casos, serão passados quaisquer argumentos nomeados adicionais como argumentos nomeados. Veja "Passando opções adicionais para funções de view" abaixo. Onde o URLconf faz sua busca ============================ O URLconf faz a busca de correspondência na URL requisitada, como uma string Python normal. Isso não inclui parâmetros GET ou POST, ou do nome de domínio. Por exemplo, numa requisição para ``http://www.example.com/myapp/``, o URLconf irá procurar por ``myapp/``. Em uma requisição para ``http://www.example.com/myapp/?page=3``, o URLconf irá procurar por ``myapp/``. O URLconf não se importa com o método de requisição. Em outras palavras, todos os métodos de requisição -- ``POST``, ``GET``, ``HEAD``, etc. -- serão roteados para a mesma função da mesma URL. A sintaxe da varivável urlpatterns ================================== ``urlpatterns`` deve ser uma lista Python no formato retornado pela função ``django.conf.urls.defaults.patterns()``. Sempre use ``patterns()`` para criar a variável ``urlpatterns``. A convenção é usar ``from django.conf.urls.defaults import *`` no topo de seu URLconf. Isso dá ao módulo acesso a estes objetos: patterns -------- .. function:: patterns(prefix, pattern_description, ...) Uma função que recebe um prefixo e um número arbitrário de padrões de URL, e retorna uma lista de padrões de URL no formato de que o Django precisa. O primeiro argumento para ``patterns()`` é uma string ``prefix``. Veja `O prefixo da view`_ abaixo. Os argumentos restantes devem ser tuplas neste formato:: (expressão regular, função de callbak Python, [, dicionário opcional [, nome opcional]]) ...onde ``dicionário opcional`` e ``nome opcional`` são opcionais. (Veja `Passando opções adicionais para funções de view`_ abaixo.) .. note:: Por `patterns()` ser uma chamada de função, ela aceita um máximo de 255 argumentos (padrões de URL, neste caso). Isso é um limite para todas as chamadas de função Python. Isso raramente é um problema na prática, porque você normalmente estrutura seus padrões de URL modularmente usando seções `include()`. Entretanto, se mesmo assim você chegar ao limite de 255 argumentos, perceba que `patterns()` retorna uma lista Python, então você pode dividir a construção da lista. :: urlpatterns = patterns('', ... ) urlpatterns += patterns('', ... ) As listas Python possuem um tamanho ilimitado, então não há um número máximo para quantos padrões de URL você pode construir. O único limite é que você só pode criar 254 de cada vez (o 255o argumento é o prefixo inicial). url --- .. versionadded:: 1.0 .. function:: url(regex, view, kwargs=None, name=None, prefix='') Você pode utilizar a função ``url()`` no lugar de uma tupla, como um argumento para ``patterns()``. Isso é conveniente se você quer especificar um nome sem utilizar o dicionário de argumentos opcionais adicionais. Por exemplo:: urlpatterns = patterns('', url(r'index/$', index_view, name="main-view"), ... ) Esta função recebe cinco argumentos, onde a maioria é opcional:: url(regex, view, kwargs=None, name=None, prefix='') Veja `Nomeando padrões de URL`_ para saber da utilidade do parâmetro ``name``. O parâmetro ``prefix`` tem o mesmo significado que o primeiro argumento de ``patterns()`` e somente é relevante quando você está passando uma string como um parâmetro para a ``view``. handler404 ---------- .. data:: handler404 Uma string representando o caminho completo para a importação Python da view que deve ser chamada se nenhum dos padrões de URL corresponder. Por padrão, este valor é ``'django.views.defaults.page_not_found'``, que na maioria das vezes deve ser suficiente. handler500 ---------- .. data:: handler500 Uma string representando o caminho completo para a importação Python da view que deve ser chamada em caso de erros no servidor. Erros no servidor acontecem quando você tem erros em tempo de execução no código da sua view. Por padrão, este valor é ``'django.views.defaults.server_error'``, que na maioria das vezes deve ser suficiente. include ------- .. function:: include() Uma função que recebe o caminho completo para a importação Python de outro URLconf que deve ser "incluído" neste local. Veja `Incluindo outros URLconfs`_ abaixo. Notas na captura de texto em URLs ================================= Cada argumento capturado é enviado para a view como uma string Python, independente do tipo de correspondência feita pela expressão regular. Por exemplo, nesta linha do URLconf:: (r'^articles/(?P\d{4})/$', 'news.views.year_archive'), ...o argumento ``year`` para ``news.views.year_archive()`` será uma string, não um inteiro, embora o ``\d{4}`` só vá corresponder a strings que contenham números inteiros. Um truque conveniente é especificar parâmetros padrão para os argumentos de suas views. Aqui vai um exemplo de URLconf e view:: # URLconf urlpatterns = patterns('', (r'^blog/$', 'blog.views.page'), (r'^blog/page(?P\d+)/$', 'blog.views.page'), ) # View (em blog/views.py) def page(request, num="1"): # Mostra a página apropriada das postagens de blog, de acordo com num. No exemplo acima, os dois padrões de URL apontam para a mesma view -- ``blog.views.page`` --, mas o primeiro padrão não captura nada da URL. Se o primeiro padrão corresponder, a função ``page()`` usará seu argumento padrão para ``num``, ``"1"``. Se o segundo padrão corresponder, ``page()`` usará o valor de ``num`` que foi capturado pela expressão regular. Performance =========== Cada expressão regular em um ``urlpatterns`` é compilada na primeira vez em que é accessada. Isso torna o sistema extremamente rápido. O prefixo da view ================= Você pode especificar um prefixo comum em sua chamada ``patterns()`` para diminuir a duplicação de código. Segue um exemplo de URLconf de :ref:`Visão geral do Django `:: from django.conf.urls.defaults import * urlpatterns = patterns('', (r'^articles/(\d{4})/$', 'mysite.news.views.year_archive'), (r'^articles/(\d{4})/(\d{2})/$', 'mysite.news.views.month_archive'), (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'mysite.news.views.article_detail'), ) Neste exemplo, cada view tem um prefixo comum -- ``'mysite.news.views'``. Em vez de digitar isso para cada entrada em ``urlpatterns``, você pode usar o primeiro argumento da função ``patterns()`` para especificar o prefixo que se aplica a cada função de view. Com isso em mente, o exemplo acima pode ser reescrito de maneira mais concisa assim:: from django.conf.urls.defaults import * urlpatterns = patterns('mysite.news.views', (r'^articles/(\d{4})/$', 'year_archive'), (r'^articles/(\d{4})/(\d{2})/$', 'month_archive'), (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'article_detail'), ) Note que você não coloca um ponto final (``"."``) no prefixo. O Django coloca isso automaticamente. Múltiplos prefixos de view -------------------------- Na prática, você provavelmente acabará misturando views ao ponto em que as views em seu ``urlpatterns`` não terão um prefixo comum. Entretanto, você ainda pode tirar vantagem do atalho de prefixo da view para remover código duplicado. Simplesmente concatene múltiplos objetos ``patterns()``, assim: Antigo:: from django.conf.urls.defaults import * urlpatterns = patterns('', (r'^$', 'django.views.generic.date_based.archive_index'), (r'^(?P\d{4})/(?P[a-z]{3})/$', 'django.views.generic.date_based.archive_month'), (r'^tag/(?P\w+)/$', 'weblog.views.tag'), ) Novo:: from django.conf.urls.defaults import * urlpatterns = patterns('django.views.generic.date_based', (r'^$', 'archive_index'), (r'^(?P\d{4})/(?P[a-z]{3})/$','archive_month'), ) urlpatterns += patterns('weblog.views', (r'^tag/(?P\w+)/$', 'tag'), ) Incluindo outros URLconfs ========================= Em qualquer ponto, seu ``urlpatterns`` pode "incluir" outros módulos URLconf. Isso essencialmente "inclui" um conjunto de URLs abaixo de outras. Por exemplo, eis o URLconf para o próprio `Web site do Django`_. Ele inclui um número de outros URLconfs:: from django.conf.urls.defaults import * urlpatterns = patterns('', (r'^weblog/', include('django_website.apps.blog.urls.blog')), (r'^documentation/', include('django_website.apps.docs.urls.docs')), (r'^comments/', include('django.contrib.comments.urls.comments')), ) Note que as expressões regulares neste exemplo não possue um ``$`` (caractere que corresponde ao final de string), mas incluem a barra final. Sempre que o Django encontra ``include()``, ele recorta qualquer parte da URL correspondida até aquele ponto e envia a string restante ao URLconf incluído para processamento adicional. .. _`Web site do Django`: http://www.djangoproject.com/ Parâmetros capturados --------------------- Um URLconf incluído recebe quaisquer parâmetros capturados do URLconf pai, então o seguinte exemplo é válido:: # Em settings/urls/main.py urlpatterns = patterns('', (r'^(?P\w+)/blog/', include('foo.urls.blog')), ) # Em foo/urls/blog.py urlpatterns = patterns('foo.views', (r'^$', 'blog.index'), (r'^archive/$', 'blog.archive'), ) No exemplo acima, a variável ``"username"`` capturada é passada para o URLconf, como esperado. Passando opções adicionais para funções de view =============================================== URLconfs possuem um "hook" que permite passar argumentos adicionais para suas funções de view como um dicionário Python. Qualquer tupla URLconf pode ter um terceiro elemento opcional, que deve ser um dicionário de argumentos nomeados adicionais a serem passados para a função de view. Por exemplo:: urlpatterns = patterns('blog.views', (r'^blog/(?P\d{4})/$', 'year_archive', {'foo': 'bar'}), ) Neste exemplo, numa requisição para ``/blog/2005/``, o Django chamará a view ``blog.views.year_archive()``, passando estes argumentos nomeados:: year='2005', foo='bar' Essa técnica é utilizada em :ref:`views genéricas ` e em :ref:`syndication framework ` para passar meta-dados e opções para as views. .. admonition:: Lidando com conflitos É possível ter um padrão de URL que captura argumentos nomeados e também passa argumentos com os mesmos nomes no seu dicionário de argumentos adicionais. Quando isso acontece, os argumentos no dicionário serão usados em vez dos argumentos capturados na URL. Passando opções adicionais para ``include()`` --------------------------------------------- Do mesmo modo, você pode passar opções adicionais para ``include()``. Quando você passa opções adicionais para ``include()``, elas serão passadas para *cada* linha no URLconf incluído. Por exemplo, estes dois conjuntos URLconf são funcionalmente idênticos: Conjunto 1:: # main.py urlpatterns = patterns('', (r'^blog/', include('inner'), {'blogid': 3}), ) # inner.py urlpatterns = patterns('', (r'^archive/$', 'mysite.views.archive'), (r'^about/$', 'mysite.views.about'), ) Conjunto 2:: # main.py urlpatterns = patterns('', (r'^blog/', include('inner')), ) # inner.py urlpatterns = patterns('', (r'^archive/$', 'mysite.views.archive', {'blogid': 3}), (r'^about/$', 'mysite.views.about', {'blogid': 3}), ) Note que as opções adicionais serão *sempre* passadas para *cada* linha no URLconf incluído, independentemente se a view da linha aceita as opções como válidas. Por este motivo, esta técnica somente é útil se você está seguro de que cada view no URLconf incluído aceita as opções adicionais que você está passando. Passando objetos que podem ser chamados (callable objects) em vez de strings ============================================================================== Alguns desenvolvedores acham mais natural passar o próprio objeto de função Python do que a string contendo o caminho para seu módulo. Esta alternativa é suportada -- você pode passar qualquer objeto que pode ser chamado como a view. Por exemplo, dado este URLconf na notação de "string":: urlpatterns = patterns('', (r'^archive/$', 'mysite.views.archive'), (r'^about/$', 'mysite.views.about'), (r'^contact/$', 'mysite.views.contact'), ) Você pode obter a mesma coisa passando objetos em vez de strings. Apenas assegure-se de importar os objetos:: from mysite.views import archive, about, contact urlpatterns = patterns('', (r'^archive/$', archive), (r'^about/$', about), (r'^contact/$', contact), ) O exemplo seguinte é funcionalmente idêntico. Somente um pouco mais compacto porque importa o módulo que contém as views, em vez de importar cada view individualmente:: from mysite import views urlpatterns = patterns('', (r'^archive/$', views.archive), (r'^about/$', views.about), (r'^contact/$', views.contact), ) O estilo que você usa fica por sua conta. Note que se você usa esta técnica -- passando objetos em vez de strings --, o prefixo da view (como explicado em "O prefixo da view" acima) não terá efeito. .. _naming-url-patterns: Nomeando padrões de URL ======================= .. versionadded:: 1.0 É bastante comum usar a mesma função de view em múltiplos padrões de URL em seu URLconf. Por exemplo, estes dois padrões de URL apontam para a view ``archive``:: urlpatterns = patterns('', (r'^archive/(\d{4})/$', archive), (r'^archive-summary/(\d{4})/$', archive, {'summary': True}), ) Isso é complemente válido, mas ocasiona problemas quando você tenta fazer uma correspondência de URL reversa (através do decorator ``permalink()`` ou a tag :ttag:`url`). Continuando este exemplo, se você quisesse recuperar a URL para a view ``archive``, o mecanismo de correspondência de URL reverso do Django ficaria confuso, pois *dois* padrões de URL apontam para esta view. Para resolver este problema, o Django suporta **padrões de URL nomeados**. Ou seja, você pode dar nomes para um padrão de URL afim de distingui-lo de outros padrões usando a mesma view e parâmetros. Então, você pode usar este nome na correspondência reversa de URL. Veja o exemplo acima, reescrito para utilizar padrões de URL nomeados:: urlpatterns = patterns('', url(r'^archive/(\d{4})/$', archive, name="full-archive"), url(r'^archive-summary/(\d{4})/$', archive, {'summary': True}, "arch-summary"), ) Com estes nomes no lugar (``full-archive`` and ``arch-summary``), você pode apontar cada padrão individualmente utilizando seu nome:: .. code-block:: html+django {% url arch-summary 1945 %} {% url full-archive 2007 %} Apesar de ambos padrões de URL referirem-se à view ``archive``, ao usar o parâmetro ``name`` de ``url()`` é possível distigui-los em templates. A string usada para o nome da URL pode conter quaisquer caracteres que você queira. Você não está restrito a nomes válidos em Python. .. note:: Quando você nomear seus padrões de URL, certifique-se de que está utilizando nomes que não têm chances óbvias de colidir com nomes escolhidos em outras aplicações. Se você chama seu padrão de URL ``comment``, e outra aplicação faz a mesma coisa, não há garantias de qual URL será inserida no seu template quando você usa este nome. Colocar um prefixo nos nomes de suas URLs, talvez derivado do nome da aplicação, diminuirá as chances de colisão. Recomendamos algo como ``myapp-comment`` em vez de ``comment``. .. _template tag: ../templates/#url Métodos utilitários =================== reverse() --------- Se você precisa usar algo similar a tag de template :ttag:`url` no seu código, o Django provê um método (no módulo ``django.core.urlresolvers``): .. function:: reverse(viewname, urlconf=None, args=None, kwargs=None) ``viewname`` é o nome da função (podendo ser uma referência para a função, ou o nome dela como uma string, se foi utilizado desta forma em ``urlpatterns``) ou o `Nome do padrão de URL`_. Normalmente, você não precisa se preocupar com o parâmetro ``urlconf`` e irá passar somente os argumentos posicionais e nomeados para serem usados na correspondência de URL. Por exemplo:: from django.core.urlresolvers import reverse def myview(request): return HttpResponseRedirect(reverse('arch-summary', args=[1945])) .. _Nome do padrão de URL: `Nomeando padrões de URL`_ A função ``reverse()`` pode reverter uma grande variedade de padrões de expressões regulares nas URLs, mas não todas. A principal restrição é quando o padrão não contém escolhas alternativas, como quando se usa o caracter barra vertical (``"|"``). Você pode utilizar esses padrões tranquilamente para corresponderem às requisições recebidas e envia-las para os views, mas você não pode reverter tais padrões. .. admonition:: Esteja certo de que suas views estão todas corretas Como parte do trabalho no qual os nomes de URL mapeiam os padrões, a função ``reverse()`` tem de importar todos os seus arquivos URLconf e examinar o nome de cada view. Isto envolve importar todos as suas funções view. Se houver *qualquer* erro enquanto importa qualquer uma de suas funções views, irá fazer o ``reverse()`` gerar um erro, mesmo que para tal função não esteja destinado o reverse. Esteja certo que qualquer view referenciado nos seus arquivos URLconf existam e que possam ser importados corretamente. Não inclua linhas que apontem para views que você ainda não criou, por que estas views não serão importáveis. resolve() --------- A função :func:`django.core.urlresolvers.resolve` pode ser usada para resolver caminhos de URL que correspondem a um funções view. Ela possui a seguinte assinatura: .. function:: resolve(path, urlconf=None) ``path`` é o caminho da URL que você deseja resolver. Como com ``reverse()`` acima, você não precisa se preocupar com o parâmetro ``urlconf``. A função retorna uma tuple tripla (função view, argumentos, argumentos nomeados). Por exemplo, ela pode ser usada para testar se um view geraria um erro ``Http404`` antes de redirecioná-lo:: from urlparse import urlparse from django.core.urlresolvers import resolve from django.http import HttpResponseRedirect, Http404 def myview(request): next = request.META.get('HTTP_REFERER', None) or '/' response = HttpResponseRedirect(next) # modifica a requisição e a resposta quando necessário, e.g. mudar # localidade e setar o cookie correspondente a localidade view, args, kwargs = resolve(urlparse(next)[2]) kwargs['request'] = request try: view(*args, **kwargs) except Http404: return HttpResponseRedirect('/') return response permalink() ----------- O decorator :func:`django.db.models.permalink`` é útil para escrever métodos curtos que retornam o caminho inteiro da URL. Por exemplo, o método ``get_absolute_url()`` do modelo. Consulte :func:`django.db.models.permalink` para mais informações.