我在生产服务器上运行了一个Django应用程序。它是用nginx后面的gunicorn 0.14.2处理的。当我重新加载应用程序(通过重新加载gunicorn工作者)时,我收到此错误:
Traceback (most recent call last):
File "/opt/nybooks/venv/myapp/lib/python2.6/site-packages/django/core/handlers/base.py", line 101, in get_response
request.path_info)
File "/opt/nybooks/venv/myapp/lib/python2.6/site-packages/django/core/urlresolvers.py", line 250, in resolve
for pattern in self.url_patterns:
File "/opt/nybooks/venv/myapp/lib/python2.6/site-packages/django/core/urlresolvers.py", line 283, in _get_url_patterns
raise ImproperlyConfigured("The included urlconf %s doesn't have any patterns in it" % self.urlconf_name)
ImproperlyConfigured: The included urlconf myapp.urls doesn't have any patterns in it
有这个问题的其他人经常注意到它在URLconf中使用reverse
时会发生,但我没有在任何URLconf中使用reverse
(也没有在任何第三方应用中使用它们)。此外,此错误仅在生产中发生 - 从未在开发中(使用Django dev服务器)或在我的登台服务器上(使用nginx后面的gunicorn 0.14.2)。在重新加载期间,它似乎也不会在任何其他时间引起该站点的麻烦。
任何想法导致问题的原因是什么?
这是主URLconf(以及堆栈跟踪中引用的URLconf):
from django.conf.urls.defaults import *
from django.contrib import admin
from django.conf import settings
from django.http import HttpResponse, Http404
from django.views.generic.simple import direct_to_template, redirect_to
from myapp.apps.magazine.views import *
from myapp.apps.books.views import *
from myapp.apps.forms.views import *
from myapp.apps.blogext.views import *
from myapp.apps.sharing.views import expand_url, email_link_send
from myapp.apps.magazine.feeds import *
from satchmo_utils import urlhelper
from satchmo_store.urls import urlpatterns
from myapp.apps.myapp_shop.views import *
admin.autodiscover()
if settings.SHOP_BASE == '':
shopregex = '^'
else:
shopregex = '^' + settings.SHOP_BASE[1:] + '/'
myapp_patterns = patterns('',
# calendar
(r'^calendar/', include('events.urls')),
# for multimedia SWF access
#(r'^crossdomain.xml$', direct_to_template, {'template': 'crossdomain.xml'}),
# intercept checkout
# TODO: need to use a config value
(r'^catalog/checkout/$', 'myapp.apps.cart.views.myapp_checkout', {'SSL': not settings.LOCAL_DEV}, 'myapp_checkout'),
(r'^catalog/add/$', 'myapp.apps.cart.views.smart_add_wrapper', {}, 'myapp_smart_add'),
# URLs for NYRB apps
(r'^$', direct_to_template, {'template': 'newhomepage.html'}),
(r'^newhomepage/$', direct_to_template, {'template': 'newhomepage.html'}),
(r'^mobile/$', redirect_to, {'url': '/', 'permanent': True}),
(r'^books/authors/', include('myapp.apps.books.urls.authors')),
(r'^books/', include('myapp.apps.books.urls.books')),
(r'^articles/', include('myapp.apps.magazine.urls.articles')),
(
r'^mobile/articles/archives/(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\d{2})/(?P<slug>[-\w]+)/$',
redirect_to,
{'url': '/articles/archives/%(year)s/%(month)s/%(day)s/%(slug)s/', 'permanent': True},
),
# for national poetry month (april)
url(
regex = r'^national-poetry-month/',
view = poetry_month,
name = 'poetry_month',
),
(r'^issues/', include('myapp.apps.magazine.urls.issues')),
(r'^contributors/', include('myapp.apps.magazine.urls.contributors')),
(r'^galleries/', include('myapp.apps.magazine.urls.illustrations')),
(r'^multimedia/', include('myapp.apps.multimedia.urls.multimedia')),
(r'^online/$', direct_to_template, {'template': 'online.html'}),
#(r'^search/', include('myapp.apps.search.urls')),
(r'^search/', include('solango.urls')),
(r'^textareas/', include('myapp.apps.textareas.urls')),
(r'', include('myapp.apps.forms.urls')),
(r'^utils/', include('myapp.apps.utils.urls')),
#(r'^rss/$', 'myapp.apps.magazine.views.rss_list'),
(r'^rss/huffpo/$', redirect_to, {'url': '/articles/feeds/huffpo/', 'permanent': False}),
(r'^rss/googlenews/$', redirect_to, {'url': '/articles/feeds/googlenews/', 'permanent': False}),
(r'^newsletter/', include('myapp.apps.newsletter.urls')),
(r'^subscriptions/', include('myapp.apps.newsubscriptions.urls')),
(r'^shared/', include('myapp.apps.sharing.urls')),
(r'^counter/', include('myapp.apps.counter.urls')),
# Redirects for legacy NYRB system
(r'^nyrev/(\w+)', uber_legacy_article_redirect),
(r'^nyrev/', redirect_to, {'url': '/'}),
(r'contents/(?P<legacy_date>\d+)/', legacy_issue_detail_redirect),
(r'^archives/browse/?$', legacy_browse_archives),
(r'^gallery/gallery-browse/?$', legacy_gallery_browse),
(r'^gallery/', legacy_illustration),
(r'authors/(?P<legacy_author_id>\d+)/', legacy_author_detail_redirect),
#(r'shop/product', legacy_book_detail_redirect),
(r'^shop/product/?$', legacy_product),
(r'^myapp/browse/?$', legacy_book_browse),
(r'blogs/myapplog/post/(\d+)/(?P<slug>[-\w]+)/$', solango_blogsearch_redirect),
# URL shortening
(r'^u/(?P<short_url>[a-zA-Z0-9]+)/$', expand_url),
# NYRB shop
(r'^shop/', include('myapp.apps.myapp_shop.urls')),
(r'^admin/shop/order/csv/?', csv_order_export_day),
(r'^admin/shop/order/(?P<order_id>\d+)/csv/?', csv_order_export),
# URLs for Savoy apps
(r'^tags/', include('savoy.contrib.sections.tag_urls')),
(r'^podcasts/', include('savoy.contrib.podcasts.urls')),
(r'^blogs/$', redirect_to, {'url': "/blogs/myapplog/", 'permanent': False}),
(r'^blogs/', include('savoy.contrib.blogs.urls')),
(r'^media/', include('savoy.core.media.urls')),
# this is to use our own edit profile view
(r'^users/(?P<username>.+)/edit/$', edit_profile),
(r'^users/', include('savoy.core.profiles.urls')),
# django-authopenid
(r'^account/getusername/', get_lost_username),
#(r'account/signin/?', 'myapp.apps.forms.views.dual_login'),
(r'account/signin/?', 'django.contrib.auth.views.login', {'template_name': 'authopenid/signin.html'}),
(r'account/signout/?', 'django.contrib.auth.views.logout', {'next_page': '/'}),
(r'account/sendpw/?', 'myapp.apps.forms.views.dual_sendpw'),
(r'account/resetpw/?', 'myapp.apps.forms.views.reset_pw'),
(r'account/signup/?', 'myapp.apps.forms.views.link_and_signup'),
#(r'^account/', include('django_authopenid.urls')),
# django-mailfriend
(r'^mail_friend/send/?', email_link_send),
(r'^mail_friend/', include('mailfriend.urls')),
# django.contrib.comments
# Django admin (Satchmo additions):
(r'^admin/print/(?P<doc>[-\w]+)/(?P<id>\d+)', 'shipping.views.displayDoc'),
(r'^admin/product/configurableproduct/(?P<id>\d+)/getoptions/', 'product.views.get_configurable_product_options'),
# Orders
(r'^admin/open-orders/$', 'myapp.apps.myapp_shop.views.open_orders'),
# Institutional subscription CSV
(r'^admin/subscriptions/institutionalsubscription\.csv', 'myapp.apps.subscriptions.views.institutional_sub_csv'),
# COUNTER admin for institutional reports
#(r'^admin/institution-counts/multiple-report/csv/$', 'myapp.apps.subscriptions.views.institution_multiple_csv'),
#(r'^admin/institution-counts/multiple-report/$', 'myapp.apps.subscriptions.views.institution_multiple_report'),
(r'^admin/institution-counts/institutions/(?P<id>\d+)/csv/', redirect_to, {'url': '/counter/%(id)s.csv'}),
(r'^admin/institution-counts/institutions/(?P<id>\d+)/$', redirect_to, {'url': '/counter/%(id)s/'}),
#(r'^admin/institution-counts/process_file/?$', 'myapp.apps.subscriptions.views.institution_process_file'),
(r'^admin/institution-counts/$', redirect_to, {'url': '/counter/'}),
# Django admin (standard)
(r'^admin/doc/', include('django.contrib.admindocs.urls')),
(r'^admin/', include(admin.site.urls)),
# custom feeds
(r'^feed/author/(?P<slug>[-\w]+)/$', AuthorFeed()),
)
# attach satchmo patterns after our patterns so we can override if needed
from satchmo_store.urls import urlpatterns
urlpatterns = myapp_patterns + urlpatterns
if settings.DEBUG:
urlpatterns += patterns('django.views.static',
(r'media/(?P<path>.*)', 'serve', {'document_root': settings.MEDIA_ROOT}),
)
答案 0 :(得分:2)
我的猜测是它与你的satchmo模式和django专门寻找的名称“urlpatterns”上的重载有关。
尝试
from satchmo_store.urls import urlpatterns as satchmo_patterns
urlpatterns = myapp_patterns + satchmo_patterns
#etc.
答案 1 :(得分:0)
奇怪的行为可能会在if settings.DEBUG
之前出现,因为某些原因,urlpatterns为空。
运行开发服务器时,会使用静态应用程序中的urlpatterns填充它。在生产中运行时,它仍然是空的。
您可以使用
这样的条款轻松检查if urlpatterns:
# something is in urlpatterns
# What's its type, contents, ...?
else:
# urlpatterns is empty
一旦你想到这一点,你就可以深入挖掘。您还可以在单元测试中添加检查,或者直接在python shell中添加检查,方法是导入urls模块,如果您想使其更加健壮。
答案 2 :(得分:0)
我认为,这只是一个预感,你的网址可能还不错,(因为你的舞台开发机没有出现任何问题,只能重新加载产品)问题可能是gunicorn重新加载模块的方式,以及方式python编译的代码在解释器的不同版本之间以及迭代器的行为方式之间起作用,但同样这些都是预感。
我建议您在分阶段计算机上使用与生产相同的python版本,看看是否可以重新创建错误,如果已经有相同的版本,那么它必须是别的,我问的原因是大多数生产机器往往使用旧版本的python,虽然我可能是错的。
祝你好运。答案 3 :(得分:0)
而不是urlpatterns = myapp_patterns + urlpatterns
这些东西,我们当然可以取而代之的是myapp_patterns
urlpatterns
,并且在它的最后部分,有以下几点:
(r'^', include('satchmo_store.urls')),
因为这是包含URL模式的“Django”方式吗?
这可能会解决您的问题,我不确定。值得一试,我想。