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)

我猜,如果你在提交之前调试你生成的表单,你会看到类似&lt;input type="hidden" name="production_id" value="None" /&gt;

【讨论】:

以上是关于Django:NoReverseMatch 错误 production_id:无的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Django 模板模式匹配错误的视图并导致 NoReverseMatch 错误?

如何解决 django 中的 NoReverseMatch 错误 [重复]

升级 Django 和 NoReverseMatch 密码错误

如何修复 NoReverseMatch Django 错误?

Django:NoReverseMatch 错误 production_id:无

Django忘记密码电子邮件系统期间的NoReverseMatch错误