Como faço para passar com êxito uma referência de função para função de Django reverse ()?

votos
10

Eu tenho um novo projeto Django marca. Eu adicionei uma função de visualização mínima para views.py, e um padrão de URL para urls.py, passando a vista por referência função em vez de uma string:

# urls.py
# -------

# coding=utf-8

from django.conf.urls.defaults import *

from myapp import views


urlpatterns = patterns('',
    url(r'^myview/$', views.myview),
)


# views.py
----------

# coding=utf-8

from django.http import HttpResponse


def myview(request):
    return HttpResponse('MYVIEW LOL',  content_type=text/plain)

Eu estou tentando usar reverse()para obter o URL, passando-a uma referência de função. Mas eu não estou recebendo uma correspondência, apesar de confirmar que a função de visualização eu estou passando para reverter é exatamente a mesma função de visualização eu coloquei no padrão de URL:

>>> from django.core.urlresolvers import reverse
>>> import urls
>>> from myapp import views

>>> urls.urlpatterns[0].callback is views.myview
True

>>> reverse(views.myview)
Traceback (most recent call last):
  File <console>, line 1, in <module>
  File /Library/Python/2.5/site-packages/django/core/urlresolvers.py, line 254, in reverse
    *args, **kwargs)))
  File /Library/Python/2.5/site-packages/django/core/urlresolvers.py, line 243, in reverse
    arguments '%s' not found. % (lookup_view, args, kwargs))
NoReverseMatch: Reverse for '<function myview at 0x6fe6b0>' with arguments '()' and keyword arguments '{}' not found.

Tanto quanto eu posso dizer a partir da documentação, referências de função deve estar bem tanto no padrão de URL e reverse().

Estou usando o tronco Django, revisão 9092.

Publicado 28/09/2008 em 20:15
fonte usuário
Em outras línguas...                            


2 respostas

votos
10

Consegui!! O problema é que algumas das importações são de myproject.myapp.views, e alguns são apenas de myapp.views. Isto é confundir o sistema de módulos Python suficiente para que ele não detecta as funções como o mesmo objeto. Isto porque o seu principal settings.pyprovavelmente tem uma linha como:

ROOT_URLCONF = `myproject.urls`

Para resolver isso, tente usar a importação completa em sua sessão de shell:

>>> from django.core.urlresolvers import reverse
>>> from myproject.myapp import views
>>> reverse(views.myview)
'/myview/'

Aqui está um registro da sessão de depuração, para quaisquer futuros leitores interessados:

>>> from django.core import urlresolvers
>>> from myapp import myview
>>> urlresolvers.get_resolver (None).reverse_dict
{None: ([(u'myview/', [])], 'myview/$'), <function myview at 0x845d17c>: ([(u'myview/', [])], 'myview/$')}
>>> v1 = urlresolvers.get_resolver (None).reverse_dict.items ()[1][0]
>>> reverse(v1)
'/myview/'
>>> v1 is myview
False
>>> v1.__module__
'testproject.myapp.views'
>>> myview.__module__
'myapp.views'

O que acontece se você mudar o jogo URL para ser r'^myview/$'?


Você já tentou fazê-lo com o nome de vista? Algo como reverse ('myapp.myview')?

É urls.pyo URLconf raiz, ou na myappaplicação? É preciso haver um caminho completo desde a raiz para uma visão para que seja resolvido. Se é isso myproject/myapp/urls.py, então, em myproject/urls.pyque você vai precisar de um código como este:

from django.conf.urls.defaults import patterns
urlpatterns = patterns ('',
    (r'^/', 'myapp.urls'),
)
Respondeu 28/09/2008 em 20:17
fonte usuário

votos
1

Se as suas duas pastas de código estão completos, então ele não se parece com o segundo, o que torna a chamada real para reverter (), já importa o módulo urls e por isso se o mapeamento url é sempre realmente alcançado.

Respondeu 28/09/2008 em 20:25
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more