1

我有一个在生产服务器上运行的 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

其他有此问题的人通常注意到它reverse在 URLconf 中使用时发生,但我没有reverse在任何 URLconfs 中使用(也没有在任何第三方应用程序中使用)。此外,这个错误发生在生产中——从不在开发中(使用 Django 开发服务器)或我的登台服务器上(在 nginx 后面使用 gunicorn 0.14.2)。在重新加载期间,它似乎也不会在任何其他时间对站点造成问题。

任何想法是什么导致了问题?


这是主要的 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}),
    )
4

4 回答 4

2

我的猜测是它与你的 satchmo 模式和 django 专门寻找的名称“urlpatterns”的重载有关。

尝试

from satchmo_store.urls import urlpatterns as satchmo_patterns
urlpatterns = myapp_patterns + satchmo_patterns

#etc.
于 2012-04-12T22:12:06.253 回答
0

I think, and this is just a hunch, your urls maybe fine, (since no issues arise in your staged dev machine, only reloading on prod) the problem maybe with the way gunicorn re-loads the modules, and the way python compiled code behaves between different versions of the interpreter and how iterators behave, but again this are all hunches.

I recommend that you use the same version of python that you have on production in your staged machine and see if you can recreate the error if there already same version, then it must be something else, the reason I ask is that most production machines tend to use older versions of python, though I could be wrong.

good luck.

于 2012-06-14T01:11:31.830 回答
0

除了这些urlpatterns = myapp_patterns + urlpatterns东西,我们当然可以myapp_patterns urlpatterns取消球棒,并在它的末端有一些类似的东西:

(r'^', include('satchmo_store.urls')),

因为这是包含 URL 模式的“Django”方式?

这可能会解决您的问题,我不确定。值得一试,我猜。

于 2012-06-14T10:28:33.770 回答
0

奇怪的行为可能是因为之前if settings.DEBUG, urlpatterns 出于某种原因是空的。

运行开发服务器时,它会填充来自静态应用程序的 urlpatterns。在生产中运行时,它仍然是空的。

您可以使用以下子句轻松检查

if urlpatterns:
    # something is in urlpatterns
    # What's its type, contents, ...?
else:
    # urlpatterns is empty

一旦你弄清楚了这一点,你就可以更深入地挖掘。您还可以在单​​元测试中添加检查,或者直接在 python shell 中进行检查,如果您想让它更健壮,请通过导入 urls 模块。

于 2012-06-09T20:09:45.667 回答