Django:NoReverseMatch 错误 production_id:无
Posted
技术标签:
【中文标题】Django:NoReverseMatch 错误 production_id:无【英文标题】:Django: NoReverseMatch Error production_id: None 【发布时间】:2016-11-04 21:49:12 【问题描述】:在填写表单时遇到问题,当我点击保存输入时,它会显示提交到 query
的信息,但我的 production_id
值将返回为 None
。
这是错误:
Environment:
Request Method: POST
Request URL: http://192.168.33.10:8000/podfunnel/episodeinfo/
Django Version: 1.9
Python Version: 2.7.6
Installed Applications:
('producer',
'django.contrib.admin',
'django.contrib.sites',
'registration',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'storages',
'django_extensions',
'randomslugfield',
'adminsortable2',
'crispy_forms')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware')
Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/generic/base.py" in view
68. return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/auth/mixins.py" in dispatch
56. return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/generic/base.py" in dispatch
88. return handler(request, *args, **kwargs)
File "/home/vagrant/fullcast_project/producer/views/pod_funnel.py" in post
601. return HttpResponseRedirect(reverse('podfunnel:episodeimagefiles', kwargs='production_id':production_id))
File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py" in reverse
600. return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))
File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py" in _reverse_with_prefix
508. (lookup_view_s, args, kwargs, len(patterns), patterns))
Exception Type: NoReverseMatch at /podfunnel/episodeinfo/
Exception Value: Reverse for 'episodeimagefiles' with arguments '()' and keyword arguments ''production_id': None' not found. 1 pattern(s) tried: [u'podfunnel/episodeimagefiles/(?P<production_id>[0-9]+)/$']
这是我的pod_funnel.py
视图:
from django.http import HttpResponseRedirect, Http404, HttpResponseForbidden
from django.shortcuts import render, get_object_or_404
from django.views.generic import View, RedirectView, TemplateView
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from .forms.client_setup import ClientSetupForm
from .forms.podcast_setup import PodcastSetupForm
from .forms.episode_info import EpisodeInfoForm
from .forms.image_files import EpisodeImageFilesForm
from .forms.wordpress_info import EpisodeWordpressInfoForm
from .forms.chapter_marks import EpisodeChapterMarksForm
from .forms.show_links import ShowLinksForm
from .forms.tweetables import TweetablesForm
from .forms.clicktotweet import ClickToTweetForm
from .forms.schedule import ScheduleForm
from .forms.wordpress_account import WordpressAccountForm
from .forms.wordpress_account_setup import WordpressAccountSetupForm
from .forms.wordpress_account_sortable import WordpressAccountSortableForm
from .forms.soundcloud_account import SoundcloudAccountForm
from .forms.twitter_account import TwitterAccountForm
from producer.helpers import get_podfunnel_client_and_podcast_for_user
from producer.helpers.soundcloud_api import SoundcloudAPI
from producer.helpers.twitter import TwitterAPI
from django.conf import settings
from producer.models import Client, Production, ChapterMark, ProductionLink, ProductionTweet, Podcast, WordpressConfig, Credentials, WordPressSortableSection, \
TwitterConfig, SoundcloudConfig
from django.core.urlresolvers import reverse
from producer.tasks.auphonic import update_or_create_preset_for_podcast
class EpisodeInfoView(LoginRequiredMixin, View):
form_class = EpisodeInfoForm
template_name = 'pod_funnel/forms_episode_info.html'
def get(self, request, *args, **kwargs):
initial_values =
user = request.user
# Lets get client and podcast for the user already. if not existent raise 404
client, podcast = get_podfunnel_client_and_podcast_for_user(user)
if client is None or podcast is None:
raise Http404
# See if a production_id is passed on the kwargs, if so, retrieve and fill current data.
# if not just provide empty form since will be new.
production_id = kwargs.get('production_id', None)
if production_id:
production = get_object_or_404(Production, id=production_id)
# Ensure this production belongs to this user, if not Unauthorized, 403
if production.podcast_id != podcast.id:
return HttpResponseForbidden()
initial_values['production_id'] = production.id
initial_values['episode_number'] = production.episode_number
initial_values['episode_title'] = production.episode_title
initial_values['episode_guest_first_name'] = production.episode_guest_first_name
initial_values['episode_guest_last_name'] = production.episode_guest_last_name
initial_values['episode_guest_twitter_name'] = production.episode_guest_twitter_name
initial_values['episode_summary'] = production.episode_summary
form = self.form_class(initial=initial_values)
return render(request, self.template_name, 'form': form)
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
client, podcast = get_podfunnel_client_and_podcast_for_user(request.user)
if form.is_valid():
# lets get the data
production_id = form.cleaned_data.get('production_id')
episode_number = form.cleaned_data.get('episode_number')
episode_title = form.cleaned_data.get('episode_title')
episode_guest_first_name = form.cleaned_data.get('episode_guest_first_name')
episode_guest_last_name = form.cleaned_data.get('episode_guest_last_name')
episode_guest_twitter_name = form.cleaned_data.get('episode_guest_twitter_name')
episode_summary = form.cleaned_data.get('episode_summary')
#if a production existed, we update, if not we create
if production_id is not None:
production = Production.objects.get(id=production_id)
else:
production = Production(podcast=podcast)
production.episode_number = episode_number
production.episode_title = episode_title
production.episode_guest_first_name = episode_guest_first_name
production.episode_guest_last_name = episode_guest_last_name
production.episode_guest_twitter_name = episode_guest_twitter_name
production.episode_summary = episode_summary
production.save()
return HttpResponseRedirect(reverse('podfunnel:episodeimagefiles', kwargs='production_id':production_id))
return render(request, self.template_name, 'form': form)
episode_info.py
表单:
from django import forms
class EpisodeInfoForm(forms.Form):
production_id = forms.IntegerField(widget=forms.Field.hidden_widget, required=False)
episode_number = forms.IntegerField(widget=forms.NumberInput, required=True)
episode_title = forms.CharField(max_length=255, required=True)
episode_guest_first_name = forms.CharField(max_length=128)
episode_guest_last_name = forms.CharField(max_length=128)
episode_guest_twitter_name = forms.CharField(max_length=64)
episode_summary = forms.CharField(widget=forms.Textarea)
还有url.py
:
from django.conf.urls import url
from django.views.generic import TemplateView
import producer.views.pod_funnel as views
urlpatterns = [
url(r'^dashboard/', views.dashboard, name="dashboard"),
url(r'^clientsetup/', views.ClientSetupView.as_view(), name="clientsetup"),
url(r'^podcastsetup/', views.PodcastSetupView.as_view(), name="podcastsetup"),
url(r'^episodeinfo/$', views.EpisodeInfoView.as_view(), name="episodeinfo"),
url(r'^episodeinfo/(?P<production_id>[0-9]+)/$', views.EpisodeInfoView.as_view(), name="episodeinfo_edit"),
url(r'^episodeimagefiles/(?P<production_id>[0-9]+)/$', views.EpisodeImageFilesView.as_view(), name="episodeimagefiles"),
如有任何建议,我们将不胜感激。
【问题讨论】:
【参考方案1】:看起来production_id
在你看来可以是None
,在这种情况下你不能在调用reverse 时使用它。最好改用production.id
。您刚刚在视图中保存了生产,因此将设置 production.id
。
return HttpResponseRedirect(reverse('podfunnel:episodeimagefiles', kwargs='production_id':production.id))
请注意,您可以使用redirect
快捷方式来简化此行。添加导入,
from django.shortcuts import redirect
然后将行改为
return redirect('podfunnel:episodeimagefiles', production_id=production.id)
【讨论】:
太棒了!感谢帮助【参考方案2】:如果您没有为production_id
提供适当的初始值,则不能始终重定向到episodeimagefiles
:
# See if a production_id is passed on the kwargs, if so, retrieve and fill current data.
# if not just provide empty form since will be new.
production_id = kwargs.get('production_id', None) <-- here you set production_id variable to None if no `production_id` in kwargs
看看你的异常:
Exception Value: Reverse for 'episodeimagefiles' with arguments '()' and keyword arguments ''production_id': None' not found. 1 pattern(s) tried: [u'podfunnel/episodeimagefiles/(?P<production_id>[0-9]+)/$']
这意味着您为 production_id
变量传递了 None
值,但 episodeimagefiles
模式需要一些 int 值来解析 url,因此它引发了 NoReverseMatch
异常。
您的表单在EpisodeInfoView.post
中有效,因为您在表单中为production_id
属性设置了required=False
:
class EpisodeInfoForm(forms.Form):
production_id = forms.IntegerField(widget=forms.Field.hidden_widget, required=False)
我猜,如果你在提交之前调试你生成的表单,你会看到类似<input type="hidden" name="production_id" value="None" />
【讨论】:
以上是关于Django:NoReverseMatch 错误 production_id:无的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Django 模板模式匹配错误的视图并导致 NoReverseMatch 错误?
如何解决 django 中的 NoReverseMatch 错误 [重复]
升级 Django 和 NoReverseMatch 密码错误
如何修复 NoReverseMatch Django 错误?