我正在使用Django 1.10和python 3.4
准确的错误是
NoReverseMatch at /movies/movie/Twilight/
Reverse for 'movie-details' with arguments '(8,)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['movies/movie/(?P<movie_id>\\d+)|(?P<movie_name>[a-zA-Z\\ ]+)/$']
错误是由以下行造成的:{em>模板 moviesrating / select_movie.html
中的{% url 'moviesrating:movie-details' movie.id %}
在文件 moviesrating / urls.py 中,正确包含在主网址文件中,有以下几行:
app_name = 'moviesrating'
urlpatterns = [
url(r'^movie/(?P<movie_id>\d+)|(?P<movie_name>[a-zA-Z\ ]+)/$', view_movie, name = 'movie-details'),
]
引用 moviesrating / views.py 中的函数 view_movie :
def view_movie(request, movie_id, movie_name):
if movie_id:
movie = get_object_or_404(Movie, pk = movie_id)
elif movie_name:
try:
movie = get_object_or_404(Movie, name = movie_name)
except MultipleObjectsReturned: # There are two movies named 'Twilight'
movies = get_list_or_404(Movie, name = movie_name)
return render(request, "moviesrating/select_movie.html", {'movies': movies})
else:
movie = None
return render(request, "moviesrating/movie.html", {'movie': movie})
网址 / movies / movie /...的目的是显示按名称或ID找到的电影,具体的网址格式来自此需求。
关键是错误显示即使它没有找到反向匹配,它也会找到正确的网址格式,所以我觉得这个模式并不匹配。然后我尝试将行更改为:
{% url 'moviesrating:movie-details' movie.id %}
{% url 'moviesrating:movie-details' movie_id=movie.id movie_name=None %}
{% url 'moviesrating:movie-details' movie.id None %}
{% url 'moviesrating.views.view_movie' movie.id %}
{% url 'moviesrating.views.view_movie' movie_id=movie.id %}
{% url 'moviesrating.views.view_movie' movie_id=movie.id movie_name=None %}
但他们都没有工作。
查看浏览器中的链接(例如 http:// localhost:8081 / movies / movie / 8 )是有效的,因此不是导致问题的页面。< / p>
此时我真的无法理解这个问题,我已经按照django docs中解释的段落阅读了已经提出的很多问题,但没有一个问题能解决我的问题。 / p>
如果有什么不清楚或需要更多信息,请告诉我,我会编辑帖子。感谢
以下是错误的完整堆栈跟踪:
Environment:
Request Method: GET
Request URL: http://localhost:8081/movies/movie/Twilight/
Django Version: 1.10.1
Python Version: 3.5.2
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'todolist.apps.TodolistConfig',
'moviesrating.apps.MoviesratingConfig']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Template error:
In template C:\Users\fra\Programmazione\Python\myserver\moviesrating\templates\moviesrating\select_movie.html, error at line 12
Reverse for 'movie-details' with arguments '(8,)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['movies/movie/(?P<movie_id>\\d+)|(?P<movie_name>[a-zA-Z\\ ]+)/$'] 2 : <html>
3 : <head>
4 : <meta charset="ISO-8859-1">
5 : <title>Choice your movie</title>
6 : </head>
7 : <body>
8 : <h2>Choice of which movie named {{ movies.0.name }} would you see the details</h2>
9 :
10 : <ul>
11 : {% for movie in movies %}
12 : <li> {% url 'moviesrating:movie-details' movie.id %} </li>
13 : <li><a href="{{ movie_url }}">{{ movie.name }} del {{ movie.year }} diretto da {{ movie.director }}</a></li>
14 : {% endfor %}
15 : </ul>
16 : </body>
17 : </html>
18 :
Traceback:
File "C:\Users\fra\Programmazione\Python\myserver\moviesrating\views.py" in view_movie
31. movie = get_object_or_404(Movie, name = movie_name)
File "C:\Program Files (x86)\Python\lib\site-packages\django\shortcuts.py" in get_object_or_404
85. return queryset.get(*args, **kwargs)
File "C:\Program Files (x86)\Python\lib\site-packages\django\db\models\query.py" in get
389. (self.model._meta.object_name, num)
During handling of the above exception (get() returned more than one Movie -- it returned 2!), another exception occurred:
File "C:\Program Files (x86)\Python\lib\site-packages\django\core\handlers\exception.py" in inner
39. response = get_response(request)
File "C:\Program Files (x86)\Python\lib\site-packages\django\core\handlers\base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "C:\Program Files (x86)\Python\lib\site-packages\django\core\handlers\base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\fra\Programmazione\Python\myserver\moviesrating\views.py" in view_movie
34. return render(request, "moviesrating/select_movie.html", {'movies': movies})
File "C:\Program Files (x86)\Python\lib\site-packages\django\shortcuts.py" in render
30. content = loader.render_to_string(template_name, context, request, using=using)
File "C:\Program Files (x86)\Python\lib\site-packages\django\template\loader.py" in render_to_string
68. return template.render(context, request)
File "C:\Program Files (x86)\Python\lib\site-packages\django\template\backends\django.py" in render
66. return self.template.render(context)
File "C:\Program Files (x86)\Python\lib\site-packages\django\template\base.py" in render
208. return self._render(context)
File "C:\Program Files (x86)\Python\lib\site-packages\django\template\base.py" in _render
199. return self.nodelist.render(context)
File "C:\Program Files (x86)\Python\lib\site-packages\django\template\base.py" in render
994. bit = node.render_annotated(context)
File "C:\Program Files (x86)\Python\lib\site-packages\django\template\base.py" in render_annotated
961. return self.render(context)
File "C:\Program Files (x86)\Python\lib\site-packages\django\template\defaulttags.py" in render
209. nodelist.append(node.render_annotated(context))
File "C:\Program Files (x86)\Python\lib\site-packages\django\template\base.py" in render_annotated
961. return self.render(context)
File "C:\Program Files (x86)\Python\lib\site-packages\django\template\defaulttags.py" in render
439. url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
File "C:\Program Files (x86)\Python\lib\site-packages\django\urls\base.py" in reverse
91. return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))
File "C:\Program Files (x86)\Python\lib\site-packages\django\urls\resolvers.py" in _reverse_with_prefix
392. (lookup_view_s, args, kwargs, len(patterns), patterns)
Exception Type: NoReverseMatch at /movies/movie/Twilight/
Exception Value: Reverse for 'movie-details' with arguments '(8,)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['movies/movie/(?P<movie_id>\\d+)|(?P<movie_name>[a-zA-Z\\ ]+)/$']
答案 0 :(得分:1)
Django的reverse()
无法处理捕获组之外的析取模式(使用|
)。这是你希望有人在过去10年左右在某处修好的事情之一,但这个限制已经在since 1.0左右。
解决方法是将模式拆分为两种模式:
urlpatterns = [
url(r'^movie/(?P<movie_id>\d+)/$', view_movie, name='movie-details'),
url(r'^movie/(?P<movie_name>[a-zA-Z\ ]+)/$', view_movie, name='movie-details'),
]
您需要为这两个参数添加默认值:
def view_movie(request, movie_id=None, movie_name=None):
...
答案 1 :(得分:0)
您只向视图发送一个参数,但它需要两个参数。如果你想坚持一个可以解释为id或名字的,为什么不接受字母数字参数
urlpatterns = [
url(r'^movie/(?P<movie_id>[A-z0-9]+)/$', view_movie, name = 'movie-details'),
]
然后在你的视图中检查它是哪一个,以便你知道你是否应该将它视为id或名称
def view_movie(request, movie_id):
try:
int(movie_id)
movie_name = False
except:
movie_name = True
if not movie_name:
movie = get_object_or_404(Movie, pk = movie_id)
elif movie_name:
# etc.
答案 2 :(得分:0)
您可以在捕获组周围添加括号:
urlpatterns = [
url(r'^movie/((?P<movie_id>\d+)|(?P<movie_name>[a-zA-Z\ ]+))/$', view_movie, name = 'movie-details'),
]
并添加默认值以查看参数:
def view_movie(request, movie_id=None, movie_name=None):
if movie_id:
return HttpResponse('1')
if movie_name:
return HttpResponse('2')
Idk为什么,但我已经在我的项目中尝试了这个并且它有效。