属性错误:模块'htmlmin.middleware'没有属性'MarkRequestMiddleware'



尝试在Heroku平台上部署我的Django应用程序,包括htmlmin和gzip,应用程序崩溃了H10错误代码。检查日志,错误似乎与

有关。AttributeError: module 'htmlmin.middleware' has no attribute 'MarkRequestMiddleware'

本地运行完美(我不知道为什么),但是在Heroku平台上部署后,应用程序无法工作。

settings.py代码:

MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
'django.middleware.gzip.GZipMiddleware',
"htmlmin.middleware.HtmlMinifyMiddleware",
"htmlmin.middleware.MarkRequestMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.locale.LocaleMiddleware",  
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",    
"django.contrib.auth.middleware.AuthenticationMiddleware",    
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware", 
]
...
HTML_MINIFY = True

这是我的requirements.txt文件:

django
django_compressor
htmlmin
gunicorn
django-heroku
pip==21.0.1
numpy==1.19.1
wordcloud==1.8.1
requests==2.24.0
urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1
matplotlib==3.3.4
wikipedia-API==0.5.3
livereload>=2.6.1
whitenoise>=5.0

Here is the Tail Log in Heroku App.

2021-09-02T18:56:35.730191+00:00 app[web.1]: mod = importlib.import_module(module)
2021-09-02T18:56:35.730191+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/importlib/__init__.py", line 127, in import_module
2021-09-02T18:56:35.730192+00:00 app[web.1]: return _bootstrap._gcd_import(name[level:], package, level)
2021-09-02T18:56:35.730192+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
2021-09-02T18:56:35.730193+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
2021-09-02T18:56:35.730193+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked        
2021-09-02T18:56:35.730193+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
2021-09-02T18:56:35.730194+00:00 app[web.1]: File "<frozen importlib._bootstrap_external>", line 850, in exec_module
2021-09-02T18:56:35.730194+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed      
2021-09-02T18:56:35.730194+00:00 app[web.1]: File "/app/biblestatistic/wsgi.py", line 16, in <module>
2021-09-02T18:56:35.730194+00:00 app[web.1]: application = get_wsgi_application()
2021-09-02T18:56:35.730195+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/core/wsgi.py", line 13, in get_wsgi_application
2021-09-02T18:56:35.730195+00:00 app[web.1]: return WSGIHandler()
2021-09-02T18:56:35.730195+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/core/handlers/wsgi.py", line 127, in __init__
2021-09-02T18:56:35.730195+00:00 app[web.1]: self.load_middleware()
2021-09-02T18:56:35.730196+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/core/handlers/base.py", line 40, in load_middleware
2021-09-02T18:56:35.730196+00:00 app[web.1]: middleware = import_string(middleware_path)
2021-09-02T18:56:35.730196+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/utils/module_loading.py", line 22, in import_string
2021-09-02T18:56:35.730197+00:00 app[web.1]: raise ImportError('Module "%s" does not define a "%s" attribute/class' % (        
2021-09-02T18:56:35.730197+00:00 app[web.1]: ImportError: Module "htmlmin.middleware" does not define a "MarkRequestMiddleware" attribute/class
2021-09-02T18:56:35.730648+00:00 app[web.1]: [2021-09-02 18:56:35 +0000] [7] [INFO] Worker exiting (pid: 7)
2021-09-02T18:56:35.940547+00:00 app[web.1]: [2021-09-02 18:56:35 +0000] [8] [ERROR] Exception in worker process
2021-09-02T18:56:35.940551+00:00 app[web.1]: Traceback (most recent call last):
2021-09-02T18:56:35.940552+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/utils/module_loading.py", line 20, in import_string
2021-09-02T18:56:35.940552+00:00 app[web.1]: return getattr(module, class_name)
2021-09-02T18:56:35.940553+00:00 app[web.1]: AttributeError: module 'htmlmin.middleware' has no attribute 'MarkRequestMiddleware'
2021-09-02T18:56:35.940553+00:00 app[web.1]:
2021-09-02T18:56:35.940553+00:00 app[web.1]: The above exception was the direct cause of the following exception:
2021-09-02T18:56:35.940554+00:00 app[web.1]:
2021-09-02T18:56:35.940554+00:00 app[web.1]: Traceback (most recent call last):
2021-09-02T18:56:35.940554+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/arbiter.py", line 589, in spawn_worker
2021-09-02T18:56:35.940555+00:00 app[web.1]: worker.init_process()
2021-09-02T18:56:35.940555+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/workers/base.py", line 134, in init_process
2021-09-02T18:56:35.940556+00:00 app[web.1]: self.load_wsgi()
2021-09-02T18:56:35.940556+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/workers/base.py", line 146, in load_wsgi
2021-09-02T18:56:35.940556+00:00 app[web.1]: self.wsgi = self.app.wsgi()
2021-09-02T18:56:35.940557+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/app/base.py", line 
67, in wsgi
2021-09-02T18:56:35.940557+00:00 app[web.1]: self.callable = self.load()
2021-09-02T18:56:35.940557+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/app/wsgiapp.py", line 58, in load
2021-09-02T18:56:35.940558+00:00 app[web.1]: return self.load_wsgiapp()
2021-09-02T18:56:35.940558+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/app/wsgiapp.py", line 48, in load_wsgiapp
2021-09-02T18:56:35.940558+00:00 app[web.1]: return util.import_app(self.app_uri)
2021-09-02T18:56:35.940559+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/util.py", line 359, in import_app
2021-09-02T18:56:35.940559+00:00 app[web.1]: mod = importlib.import_module(module)
2021-09-02T18:56:35.940560+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/importlib/__init__.py", line 127, in import_module
2021-09-02T18:56:35.940560+00:00 app[web.1]: return _bootstrap._gcd_import(name[level:], package, level)
2021-09-02T18:56:35.940560+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
2021-09-02T18:56:35.940561+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
2021-09-02T18:56:35.940561+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked        
2021-09-02T18:56:35.940561+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
2021-09-02T18:56:35.940562+00:00 app[web.1]: File "<frozen importlib._bootstrap_external>", line 850, in exec_module
2021-09-02T18:56:35.940562+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed      
2021-09-02T18:56:35.940562+00:00 app[web.1]: File "/app/biblestatistic/wsgi.py", line 16, in <module>
2021-09-02T18:56:35.940562+00:00 app[web.1]: application = get_wsgi_application()
2021-09-02T18:56:35.940563+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/core/wsgi.py", line 13, in get_wsgi_application
2021-09-02T18:56:35.940563+00:00 app[web.1]: return WSGIHandler()
2021-09-02T18:56:35.940563+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/core/handlers/wsgi.py", line 127, in __init__
2021-09-02T18:56:35.940563+00:00 app[web.1]: self.load_middleware()
2021-09-02T18:56:35.940564+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/core/handlers/base.py", line 40, in load_middleware
2021-09-02T18:56:35.940564+00:00 app[web.1]: middleware = import_string(middleware_path)
2021-09-02T18:56:35.940564+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/utils/module_loading.py", line 22, in import_string
2021-09-02T18:56:35.940565+00:00 app[web.1]: raise ImportError('Module "%s" does not define a "%s" attribute/class' % (        
2021-09-02T18:56:35.940565+00:00 app[web.1]: ImportError: Module "htmlmin.middleware" does not define a "MarkRequestMiddleware" attribute/class
2021-09-02T18:56:35.940826+00:00 app[web.1]: [2021-09-02 18:56:35 +0000] [8] [INFO] Worker exiting (pid: 8)
2021-09-02T18:56:36.110011+00:00 app[web.1]: Traceback (most recent call last):
2021-09-02T18:56:36.110030+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/arbiter.py", line 209, in run
2021-09-02T18:56:36.110342+00:00 app[web.1]: self.sleep()
2021-09-02T18:56:36.110354+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/arbiter.py", line 357, in sleep
2021-09-02T18:56:36.110545+00:00 app[web.1]: ready = select.select([self.PIPE[0]], [], [], 1.0)
2021-09-02T18:56:36.110555+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/arbiter.py", line 242, in handle_chld
2021-09-02T18:56:36.113107+00:00 app[web.1]: self.reap_workers()
2021-09-02T18:56:36.113121+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/arbiter.py", line 525, in reap_workers
2021-09-02T18:56:36.113423+00:00 app[web.1]: raise HaltServer(reason, self.WORKER_BOOT_ERROR)
2021-09-02T18:56:36.113475+00:00 app[web.1]: gunicorn.errors.HaltServer: <HaltServer 'Worker failed to boot.' 3>
2021-09-02T18:56:36.113485+00:00 app[web.1]: 
2021-09-02T18:56:36.113486+00:00 app[web.1]: During handling of the above exception, another exception occurred:
2021-09-02T18:56:36.113486+00:00 app[web.1]:
2021-09-02T18:56:36.113488+00:00 app[web.1]: Traceback (most recent call last):
2021-09-02T18:56:36.113502+00:00 app[web.1]: File "/app/.heroku/python/bin/gunicorn", line 8, in <module>
2021-09-02T18:56:36.113595+00:00 app[web.1]: sys.exit(run())
2021-09-02T18:56:36.113609+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/app/wsgiapp.py", line 67, in run
2021-09-02T18:56:36.113695+00:00 app[web.1]: WSGIApplication("%(prog)s [OPTIONS] [APP_MODULE]").run()
2021-09-02T18:56:36.113704+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/app/base.py", line 
231, in run
2021-09-02T18:56:36.113838+00:00 app[web.1]: super().run()
2021-09-02T18:56:36.113848+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/app/base.py", line 
72, in run
2021-09-02T18:56:36.113938+00:00 app[web.1]: Arbiter(self).run()
2021-09-02T18:56:36.113948+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/arbiter.py", line 229, in run
2021-09-02T18:56:36.114078+00:00 app[web.1]: self.halt(reason=inst.reason, exit_status=inst.exit_status)
2021-09-02T18:56:36.114093+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/arbiter.py", line 342, in halt
2021-09-02T18:56:36.114250+00:00 app[web.1]: self.stop()
2021-09-02T18:56:36.114263+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/arbiter.py", line 393, in stop
2021-09-02T18:56:36.114415+00:00 app[web.1]: time.sleep(0.1)
2021-09-02T18:56:36.114426+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/arbiter.py", line 242, in handle_chld
2021-09-02T18:56:36.114545+00:00 app[web.1]: self.reap_workers()
2021-09-02T18:56:36.114554+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/arbiter.py", line 525, in reap_workers
2021-09-02T18:56:36.114751+00:00 app[web.1]: raise HaltServer(reason, self.WORKER_BOOT_ERROR)
2021-09-02T18:56:36.114787+00:00 app[web.1]: gunicorn.errors.HaltServer: <HaltServer 'Worker failed to boot.' 3>
2021-09-02T18:56:36.202731+00:00 heroku[web.1]: Process exited with status 1
2021-09-02T18:56:36.281947+00:00 heroku[web.1]: State changed from starting to crashed
2021-09-02T18:58:20.408763+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=biblestatistic-test.herokuapp.com request_id=54789e04-96e4-4cd6-b4e2-b4d900ece656 fwd="177.221.50.1" dyno= connect= service= status=503 bytes= protocol=https

这是Build日志

-----> Building on the Heroku-20 stack
-----> Using buildpack: heroku/python
-----> Python app detected
-----> Using Python version specified in runtime.txt
!     Python has released a security update! Please consider upgrading to python-3.9.7
Learn More: https://devcenter.heroku.com/articles/python-runtimes
-----> No change in requirements detected, installing from cache
-----> Using cached install of python-3.9.6
-----> Installing pip 20.2.4, setuptools 47.1.1 and wheel 0.36.2
-----> Installing SQLite3
-----> Installing requirements with pip
Collecting pip==21.0.1
Downloading pip-21.0.1-py3-none-any.whl (1.5 MB)
Installing collected packages: pip
Attempting uninstall: pip
Found existing installation: pip 20.2.4
Uninstalling pip-20.2.4:
Successfully uninstalled pip-20.2.4
Successfully installed pip-21.0.1
-----> $ python manage.py collectstatic --noinput
Found another file with the destination path 'lang-logo.png'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'images/favicon-16x16.png'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'images/bs_blue.png'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'images/cloud-header.png'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'images/bs-logo.png'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'images/en.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'images/es.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'images/arrow-right-transparent-smaller.png'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'images/favicon.ico'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'images/404.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'images/favicon-32x32.png'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'images/pt-br.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'images/prj/bs_blue.png'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'images/prj/bs_blue.xcf'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'js/bootstrap-modal-ios.js'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'js/bundle.js'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'css/theme.css'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'css/styles.css'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'css/default.css'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'css/theme.min.css'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'css/styles.min.css'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'css/default.min.css'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
150 static files copied to '/tmp/build_ba093552/staticfiles', 466 post-processed.
-----> Discovering process types
Procfile declares types -> web
-----> Compressing...
Done: 235.2M
-----> Launching...
Released v20
https://myapp.herokuapp.com/ deployed to Heroku

关于如何修复这个错误有什么建议吗?

谢谢,

我建议总是尝试在"django.contrib.sessions.middleware.SessionMiddleware",之后使用其他中间件,因为有时会话数据加载与新的开始和其他中间件不能完美地工作。

试试这样>>>

MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.locale.LocaleMiddleware",  
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",    
"django.contrib.auth.middleware.AuthenticationMiddleware",    
"django.contrib.messages.middleware.MessageMiddleware",
'django.middleware.gzip.GZipMiddleware',
"htmlmin.middleware.HtmlMinifyMiddleware",
"htmlmin.middleware.MarkRequestMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware", 
]

它可能工作。如果没有,这永远是最佳实践。

这是我找到的解决方案。

  1. 修改requirements.txthtmlmindjango-htmlmin的依赖性
  2. 包含settings.pyfrom htmlmin.minify import html_minify为参考。原因是基于原始库中的middleware.py文件,只是为了保证HtmlMinifyMiddleware类和MarkRequestMiddleware
  3. 之间的关系。

当在Heroku中部署时效果很好。

最新更新