{"id":344644,"date":"2023-01-29T15:01:50","date_gmt":"2023-01-29T15:01:50","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=344644"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=344644","title":{"rendered":"<span>React+Django \u043a\u0430\u043a \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c Hello World<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h4>\u041d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 react \u0441 \u0431\u044d\u043a\u0435\u043d\u0434\u043e\u043c \u043d\u0430 Django, \u0441 \u0411\u0414 \u043d\u0430 postgres, \u0437\u0430\u0439\u0446\u0435\u043c, nginx \u0438 \u0432\u0441\u0451 \u0437\u0430\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0432 docker.<\/h4>\n<p>\u0414\u043b\u044f \u043a\u043e\u0433\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f?  \u041f\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u043c\u0443 \u0441\u0447\u0435\u0442\u0443 \u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0433\u043e \u0441\u0435\u0431\u044f, \u0447\u0442\u043e\u0431\u044b \u0445\u043e\u0442\u044c \u043a\u0430\u043a-\u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u043d\u0438\u044f \u0432 \u0441\u0432\u043e\u0435\u0439 \u0447\u0435\u0440\u0435\u043f\u0443\u0448\u043a\u0435. \u0410 \u0442\u0430\u043a\u0436\u0435 \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u0430 \u0442\u0430\u043a\u0438\u043c \u0436\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438, \u043a\u0430\u043a \u0438 \u044f \u0441\u0430\u043c. \u0412\u0441\u0451 \u0447\u0442\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u043d\u0438\u0436\u0435, \u043d\u0435 \u043f\u0440\u0435\u0442\u0435\u043d\u0434\u0443\u0435\u0442 \u043d\u0430 \u0438\u0441\u0442\u0438\u043d\u0443 \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u0438\u043d\u0441\u0442\u0430\u043d\u0446\u0438\u0438. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u043c\u0435\u0441\u0442\u0430\u043c\u0438 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0442\u0430\u043a, \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u044e\u0442. \u041d\u043e \u0442\u0430\u043a \u043a\u0430\u043a \u0443 \u043c\u0435\u043d\u044f \u043d\u0435 \u0441\u0442\u043e\u044f\u043b\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c enterprise \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0430 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0449\u0443\u043f\u0430\u0442\u044c \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a \u044d\u0442\u043e \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0442\u043e \u0432 \u0446\u0435\u043b\u043e\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u0435\u043d\u044f \u0443\u0441\u0442\u0440\u043e\u0438\u043b.<\/p>\n<p>\u0414\u043e\u043b\u0436\u0435\u043d \u0441\u0440\u0430\u0437\u0443 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0434\u0438\u0442\u044c, \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435 100% \u043b\u0438\u0447\u043d\u0430\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430. \u042d\u0442\u043e \u043f\u0440\u043e\u0435\u043a\u0442 \u0424\u0440\u0430\u043d\u043a\u0435\u043d\u0448\u0442\u0435\u0439\u043d \u0438\u0437 \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0442\u0430\u0442\u0435\u0439 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0430. \u041e\u0434\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435\u0439 \u044f \u043d\u0435 \u0441\u043c\u043e\u0433 \u043d\u0430\u0439\u0442\u0438, \u0438 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0441\u043b\u0435 \u0441\u0431\u043e\u0440\u043a\u0438 \u043d\u0430\u0447\u0430\u043b \u043f\u0438\u0441\u0430\u0442\u044c \u044d\u0442\u0443, \u0447\u0442\u043e\u0431\u044b \u0442\u0435, \u043a\u043e\u043c\u0443 \u044d\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0438 \u043f\u043e\u0449\u0443\u043f\u0430\u0442\u044c.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/07d\/5c9\/b5a\/07d5c9b5a96baf4dc4c0cc68477653a0.png\" alt=\"\u041d\u0430\u0447\u043d\u0451\u043c \u043f\u043e\u0436\u0430\u043b\u0443\u0439\" title=\"\u041d\u0430\u0447\u043d\u0451\u043c \u043f\u043e\u0436\u0430\u043b\u0443\u0439\" width=\"363\" height=\"332\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/07d\/5c9\/b5a\/07d5c9b5a96baf4dc4c0cc68477653a0.png\"\/><figcaption>\u041d\u0430\u0447\u043d\u0451\u043c \u043f\u043e\u0436\u0430\u043b\u0443\u0439<\/figcaption><\/figure>\n<p>\u041d\u0430\u0447\u043d\u0443 \u044f \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430.<\/p>\n<p>\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 WEB \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 React. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u043e\u0432, \u0441 \u043f\u0430\u0447\u043a\u043e\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0445 \u043f\u043e\u043b\u0435\u0439, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a \u0438\u043c\u044f, \u043f\u043e\u0447\u0442\u0430 \u0442\u0435\u043b\u0435\u0444\u043e\u043d \u0438 \u043f\u0440\u043e\u0447\u0435\u0435. \u0422\u0430\u043a \u0436\u0435 \u043a \u044d\u0442\u043e\u043c\u0443 \u0432\u0441\u0435\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u0438\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435. \u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a \u0436\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442. \u041c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u0430, \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0438\u043b\u0438 \u0436\u0435 \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435.<\/p>\n<p>\u0425\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u043d\u0430\u0448\u0438 \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u044b \u0431\u0443\u0434\u0443\u0442 \u043a\u0430\u043a \u0432\u044b \u0443\u0436\u0435 \u043f\u043e\u043d\u044f\u043b\u0438 \u0432 \u0411\u0414 postgress, \u0430 \u0432\u043e\u0442 \u0431\u0435\u0440\u0435\u0436\u043d\u043e \u0438\u0445 \u0442\u0443\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0435\u043c\u0438 \u043b\u044e\u0431\u0438\u043c\u0430\u044f Django \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043c\u0438 Django rest framework.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/bf3\/2f7\/4c8\/bf32f74c84338b651e3ac8ad6e864577.png\" width=\"973\" height=\"305\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bf3\/2f7\/4c8\/bf32f74c84338b651e3ac8ad6e864577.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0437\u0430\u0445\u043e\u0434\u0438\u0442 \u043d\u0430 \u0432\u0435\u0431 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443. React \u0442\u043e\u043f\u0430\u0435\u0442 \u043d\u0430 Django \u0447\u0435\u0440\u0435\u0437 nginx, \u0437\u0430\u0431\u0438\u0440\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0441\u0442\u0440\u043e\u0438\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438. \u041c\u044b \u0432\u043e\u043b\u044c\u043d\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e. \u0417\u0430\u043a\u043e\u043d\u043e\u043c\u0435\u0440\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441, \u0437\u0430\u0447\u0435\u043c \u0432 \u044d\u0442\u043e\u0439 \u0441\u0445\u0435\u043c\u0435 Rabbit \u0438 \u0434\u0432\u0430 worker\u2019\u0430? \u0412\u0441\u0451 \u0434\u0435\u043b\u043e \u0432 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438\/\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u043d\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432 \u0444\u043e\u0440\u043c\u0443, \u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u043d\u043e\u0432\u044f\u0442\u0441\u044f, \u043d\u0435 \u0437\u0430\u0442\u0440\u0430\u0433\u0438\u0432\u0430\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435. \u041d\u043e \u0435\u0441\u043b\u0438 \u0442\u0430\u043a\u0438 \u043c\u044b \u0440\u0435\u0448\u0438\u043c \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u0438\u0442\u044c, \u0442\u043e \u0432\u0441\u0442\u0443\u043f\u0430\u0435\u0442 \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u044f \u0431\u0443\u0440\u043d\u043e\u0439 \u0434\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438\u043c\u044f, \u0438 \u043f\u043e\u043b\u0435 photo \u043d\u0430\u0448\u0435\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0443\u0442\u044c \u043a \u043d\u0435\u043c\u0443. \u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043d\u0430 rabbit \u0438 \u0432\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u0442\u0443\u0434\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c. Worker \u0437\u0430\u0431\u0438\u0440\u0430\u0435\u0442 \u0435\u0433\u043e, \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u0438 \u0448\u043b\u0451\u0442 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 \u0434\u0440\u0443\u0433\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c. \u0412\u0442\u043e\u0440\u043e\u0439 worker \u0437\u0430\u0431\u0438\u0440\u0430\u0435\u0442 \u0435\u0433\u043e \u0438 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u043f\u043e \u0443\u0436\u0435 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u043c\u0443 \u0432\u044b\u0448\u0435 \u043f\u0443\u0442\u0438. \u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0443\u0439\u0442\u0438 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0432\u0440\u0435\u043c\u044f, \u043d\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f \u043b\u0438\u0431\u043e \u0441\u0440\u0430\u0437\u0443, \u043b\u0438\u0431\u043e \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.   <\/p>\n<p>\u0412\u043e\u0442 \u0432 \u0446\u0435\u043b\u043e\u043c \u0438 \u0432\u0441\u0451.\u00a0 \u0427\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u043d\u0430\u0442\u044c \u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a \u0434\u0435\u043b\u0443, \u044f \u0432\u0441\u0435 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0434\u0435\u043b\u044b\u0432\u0430\u043b \u043d\u0430 windows, \u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u043b \u0443\u0436\u0435 \u043d\u0430 centos. <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/p>\n<p>\u042f \u043d\u0430\u0437\u0432\u0430\u043b \u0435\u0433\u043e ProjectStudent.<\/p>\n<p>1) Django.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0434\u043b\u044f Django \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u043d\u0435\u0433\u043e.<\/p>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u0432 \u044d\u0442\u043e\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 PowerShell (\u0438\u043b\u0438 cmd, \u043a\u043e\u043c\u0443 \u043a\u0430\u043a \u0443\u0434\u043e\u0431\u043d\u0435\u0435. \u0412 bash \u043c\u043e\u0436\u0435\u0442 \u043d\u0435\u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u0442\u044c\u0441\u044f)<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0438 \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e<\/p>\n<pre><code class=\"bash\">python3 -m venv --copies .\/env .\\env\\Scripts\\activate<\/code><\/pre>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c Django, \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u0441\u0440\u0430\u0437\u0443 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/p>\n<pre><code class=\"bash\">pip install Django django-admin startproject django_project python manage.py startapp students<\/code><\/pre>\n<p>\u0418\u0437 \u0442\u043e\u0433\u043e \u0447\u0442\u043e \u043d\u0430\u043c \u0435\u0449\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0432 Django \u0441\u0440\u0430\u0437\u0443 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c djangorestframework \u0438 django-cors-headers<\/p>\n<pre><code class=\"bash\">pip install django djangorestframework django-cors-headers<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c.<\/p>\n<p>\u041e\u0442\u043a\u0440\u043e\u0435\u043c \u0444\u0430\u0439\u043b django\\django_project\\django_project\\settings.py<\/p>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u044b \u043d\u0430 \u0431\u0443\u0434\u0443\u0449\u0435\u0435, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, middleware<\/p>\n<pre><code class=\"python\">import os from pathlib import Path from os import environ  INSTALLED_APPS = [     ...     'rest_framework',     'corsheaders',     'students' ]  MIDDLEWARE = [     ...     'corsheaders.middleware.CorsMiddleware',     'django.middleware.common.CommonMiddleware', ]<\/code><\/pre>\n<p>CORS_ORIGIN_ALLOW_ALL\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u0434\u043e\u043b\u0436\u0435\u043d \u043b\u0438 Django \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u0442\u043a\u0440\u044b\u0442 \u0438\u043b\u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0437\u0430\u043a\u0440\u044b\u0442 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u043d\u0430\u043c \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u044d\u0442\u043e \u043d\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0435\u0433\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c.<\/p>\n<pre><code class=\"python\">CORS_ORIGIN_ALLOW_ALL = True<\/code><\/pre>\n<p>\u0418 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u0438\u043a\u0438<\/p>\n<pre><code class=\"python\">STATIC_URL = '\/static\/' STATIC_ROOT = os.path.join(BASE_DIR, 'static')  MEDIA_URL = '\/media\/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')<\/code><\/pre>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e. \u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u0439\u043c\u0435\u043c\u0441\u044f \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u0430\u043c\u0438.<\/p>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043c\u043e\u0434\u0435\u043b\u044c django\\django_project\\students\\models.py <\/p>\n<p>\u0438 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043c\u043e\u0434\u0435\u043b\u044c<\/p>\n<pre><code class=\"python\">from django.db import models  class Student(models.Model):     name = models.CharField(\"Name\", max_length=240)     email = models.EmailField()     document = models.CharField(\"Document\", max_length=20)     phone = models.CharField(max_length=20)     registrationDate = models.DateField(\"Registration Date\", auto_now_add=True)     photo = models.CharField(\"URL\", max_length=512)      def __str__(self):         return self.name<\/code><\/pre>\n<p>\u0413\u043e\u0442\u043e\u0432\u043e. \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0432\u0441\u0451 \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b\u044b \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438 \u0438 \u043c\u0438\u0433\u0440\u0438\u0440\u0443\u0435\u043c.<\/p>\n<pre><code class=\"bash\">Python manage.py makemigrations python manage.py migrate<\/code><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0441\u0438\u043b\u044c\u043d\u043e \u0437\u0430\u043c\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438 \u0444\u0438\u043a\u0441\u0442\u0443\u0440\u0430\u043c\u0438, \u0441\u0440\u0430\u0437\u0443 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0444\u0430\u0439\u043b \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u0443\u0434\u0430.<\/p>\n<pre><code class=\"bash\">python manage.py makemigrations --empty --name students students<\/code><\/pre>\n<p>\u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043d\u0430\u0434\u043e \u043f\u043e\u0434\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0444\u0430\u0439\u043b django\\django_project\\students\\migrations\\0002_students.py<\/p>\n<p>\u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043c \u0435\u0433\u043e \u043a \u0442\u0430\u043a\u043e\u043c\u0443 \u0432\u0438\u0434\u0443:<\/p>\n<pre><code class=\"python\">from django.db import migrations  def create_data(apps, schema_editor):     Student = apps.get_model('students', 'Student')     Student(name=\"Joe Silver\", email=\"joe@email.com\", document=\"22342342\", phone=\"00000000\", photo='media\/photo\/nophoto.png').save()     Student(name=\"John Smith\", email=\"john@email.com\", document=\"11111111\", phone=\"11111111\", photo='media\/photo\/nophoto.png').save()     Student(name=\"Alex Smth\", email=\"alex@email.com\", document=\"22222222\", phone=\"22222222\", photo='media\/photo\/nophoto.png').save()     Student(name=\"Kira Night\", email=\"kira@email.com\", document=\"33333333\", phone=\"33333333\", photo='media\/photo\/nophoto.png').save()     Student(name=\"Amanda Lex\", email=\"amanda@email.com\", document=\"44444444\", phone=\"44444444\", photo='media\/photo\/nophoto.png').save()     Student(name=\"Oni Musha\", email=\"oni@email.com\", document=\"44444444\", phone=\"44444444\", photo='media\/photo\/nophoto.png').save()  class Migration(migrations.Migration):      dependencies = [         ('students', '0001_initial'),     ]      operations = [         migrations.RunPython(create_data),     ] <\/code><\/pre>\n<p>\u0418 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043c \u0435\u0449\u0451 \u043e\u0434\u043d\u0443 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044e<\/p>\n<pre><code class=\"bash\">python manage.py migrate<\/code><\/pre>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e! \u0422\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u043d\u0430\u0448\u0435\u043c\u0443 api<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043d\u0430\u0448\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445. \u0444\u0430\u0439\u043b django\\django_project\\students\\serializers.py<\/p>\n<pre><code class=\"python\">from rest_framework import serializers from .models import Student  class StudentSerializer(serializers.ModelSerializer):      class Meta:         model = Student          fields = ('pk', 'name', 'email', 'document', 'phone', 'registrationDate','photo') <\/code><\/pre>\n<p>\u0442\u0430\u043a, \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0432 uls.py, \u0430\u0434\u0440\u0435\u0441\u0430 \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043d\u0430\u0448\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c django\\django_project\\django_project\\urls.py <\/p>\n<p>\u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e re_path, \u043d\u0430\u0448\u0435 \u0441\u0442\u0443\u0434\u0435\u043d\u0447\u0435\u0441\u043a\u043e\u0435 view \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u0438\u043a\u0438.<\/p>\n<pre><code class=\"python\">from django.contrib import admin from django.urls import path, re_path from students import views from django.conf import settings from django.conf.urls.static import static  urlpatterns = [     path('admin\/', admin.site.urls),     re_path(r'^api\/students\/$', views.students_list),     re_path(r'^api\/students\/(\\d+)$', views.students_detail), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u043a view<\/p>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c django\\django_project\\students\\views.py<\/p>\n<pre><code class=\"python\">from rest_framework.response import Response from rest_framework.decorators import api_view from rest_framework import status from .serializers import *  # Create your views here.  @api_view(['GET', 'POST']) def students_list(request):     if request.method == 'GET':         data = Student.objects.all()         serializer = StudentSerializer(data, context={'request': request}, many=True)         return Response(serializer.data)     elif request.method == 'POST':         print('post')         serializer = StudentSerializer(data=request.data)         if serializer.is_valid():             serializer.save()             return Response(status=status.HTTP_201_CREATED)         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)  @api_view(['PUT', 'DELETE']) def students_detail(request, pk):     try:         student = Student.objects.get(pk=pk)     except Student.DoesNotExist:         return Response(status=status.HTTP_404_NOT_FOUND)     if request.method == 'PUT':         serializer = StudentSerializer(student, data=request.data, context={'request': request})         if serializer.is_valid():             serializer.save()             return Response(status=status.HTTP_204_NO_CONTENT)         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)     elif request.method == 'DELETE':         student.delete()         return Response(status=status.HTTP_204_NO_CONTENT)  <\/code><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0443\u0431\u0435\u0434\u0438\u043c\u0441\u044f, \u0447\u0442\u043e \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440<\/p>\n<pre><code class=\"bash\">python manage.py runserver<\/code><\/pre>\n<p>\u0438 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 <a href=\"http:\/\/127.0.0.1:8000\/api\/students\/\" rel=\"noopener noreferrer nofollow\">http:\/\/127.0.0.1:8000\/api\/students\/<\/a><\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/953\/3ad\/bcd\/9533adbcd9ea02826370dc7f9152e5ef.png\" width=\"907\" height=\"377\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/953\/3ad\/bcd\/9533adbcd9ea02826370dc7f9152e5ef.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0412\u0438\u0434\u0438\u043c \u043d\u0430\u0448\u0438\u0445 \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u043e\u0432. \u0417\u043d\u0430\u0447\u0438\u0442 \u0432\u0441\u0451 \u043e\u043a!<\/p>\n<p>\u0422\u0430\u043a \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u044b \u0441 django \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438, \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a react.<\/p>\n<p>\u0422\u0430\u043c \u043f\u0438\u0441\u0430\u043d\u0438\u043d\u044b \u043f\u043e\u0431\u043e\u043b\u044c\u0448\u0435 \u0431\u0443\u0434\u0435\u0442, \u043d\u043e \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043a\u043e\u0434. \u041f\u043e\u0435\u0445\u0430\u043b\u0438!<\/p>\n<p>\u041a\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435?<\/p>\n<p>App \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0434\u0432\u0443\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, Header \u0438 Home. \u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c Home \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 ListStudents \u0438 ModalStudent (\u043a\u043d\u043e\u043f\u043a\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u0430)<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/03c\/90a\/50a\/03c90a50a94aec495e6681ab373812bf.png\" width=\"1181\" height=\"400\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/03c\/90a\/50a\/03c90a50a94aec495e6681ab373812bf.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0412\u044b\u0445\u043e\u0434\u0438\u043c \u0432 \u043a\u043e\u0440\u043d\u0435\u0432\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443<\/p>\n<pre><code class=\"bash\">npx create-react-app reactapp<\/code><\/pre>\n<p>\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u043f\u0430\u0440\u0443 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 <\/p>\n<pre><code class=\"bash\">npm i axios reactstrap bootstrap<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u043e\u0437\u0434\u0430\u043b\u043e\u0441\u044c, \u043d\u0430\u0447\u043d\u0435\u043c \u043d\u0430\u043a\u0438\u0434\u044b\u0432\u0430\u0442\u044c \u0432 \u043d\u0435\u0433\u043e \u0441\u0432\u043e\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432 src \u043a\u0430\u0442\u0430\u043b\u043e\u0433 components, \u0438 \u0432 \u043f\u043e\u0434\u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0438 app, appHeader, appHome, appListStudents, appModalStudent, appPhotoModal, appRemoveStudent,appStudentForm.<\/p>\n<p>\u041a\u0430\u043a \u0432\u044b \u043f\u043e\u043d\u044f\u043b\u0438, \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 \u0438 \u0444\u0430\u0439\u043b\u0435. <\/p>\n<p>\u0412 app \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0438\u043c, \u043f\u043e \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u043e js \u0444\u0430\u0439\u043b\u0443 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/adb\/9ab\/2b0\/adb9ab2b05136b9e23dc2020eb064729.png\" alt=\"\u0412 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a.\" title=\"\u0412 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a.\" width=\"219\" height=\"550\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/adb\/9ab\/2b0\/adb9ab2b05136b9e23dc2020eb064729.png\"\/><figcaption>\u0412 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a.<\/figcaption><\/figure>\n<p>\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u043a \u043a\u043e\u0434\u0443 react \u044f \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e \u043d\u0435 \u0434\u0435\u043b\u0430\u043b, \u0442\u0430\u043c \u0432\u0441\u0451 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u0445. \u0422\u0430\u043c \u0433\u0434\u0435 \u044f \u044d\u0442\u043e \u043f\u043e\u0434\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u043b \u0432\u0441\u0451 \u0431\u044b\u043b\u043e \u0432 \u043a\u043b\u0430\u0441\u0441\u043e\u0432\u044b\u0445, \u043d\u043e \u0442.\u043a. \u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0437\u043d\u0430\u044e react \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0437 \u043a\u043b\u0430\u0441\u0441\u043e\u0432\u044b\u0445 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0443 \u043c\u0435\u043d\u044f \u043d\u0435 \u043f\u0440\u043e\u043a\u0430\u0442\u0438\u043b\u043e, \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0432\u0441\u0451 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441 \u043d\u0443\u043b\u044f, \u043f\u043e\u0434\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u044f \u0432 \u0448\u043f\u0430\u0440\u0433\u0430\u043b\u043a\u0443.<\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u0432\u0435\u0440\u0445\u0443 \u0438 \u043f\u043e\u0439\u0434\u0451\u043c \u0432\u043d\u0438\u0437.<\/p>\n<p>App.js \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/p>\n<pre><code class=\"javascript\">import '.\/App.css'; import {Fragment} from \"react\"; import Header from \"..\/appHeader\/Header\"; import Home from \"..\/appHome\/Home\";  function App() {     return (         &lt;Fragment>             &lt;Header\/>             &lt;Home\/>         &lt;\/Fragment>     ); }  export default App;<\/code><\/pre>\n<p>Header.js \u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a<\/p>\n<pre><code class=\"javascript\">const Header = () => {     return (         &lt;div className=\"text-center\">             &lt;img                 src=\"https:\/\/cdn.worldvectorlogo.com\/logos\/react-2.svg\"                 width=\"100\"                 className=\"img-thumbnail\"                 style={{marginTop: \"20px\"}}                 alt=\"logo\"             \/>             &lt;hr\/>             &lt;h1>App for project on React + Django&lt;\/h1>         &lt;\/div>) }  export default Header;<\/code><\/pre>\n<p>Home.js \u0414\u0430\u043d\u043d\u044b\u0435<\/p>\n<pre><code class=\"javascript\">import {Container, Row, Col} from \"reactstrap\"; import ListStudents from \"..\/appListStudents\/ListStudents\"; import axios from \"axios\"; import {useEffect, useState} from \"react\"; import ModalStudent from \"..\/appModalStudent\/ModalStudent\"; import {API_URL} from \"..\/..\/index\";  const Home = () => {     const [students, setStudents] = useState([])      useEffect(()=>{         getStudents()     },[])      const getStudents = (data)=>{         axios.get(API_URL).then(data => setStudents(data.data))     }      const resetState = () => {         getStudents();     };      return (         &lt;Container style={{marginTop: \"20px\"}}>             &lt;Row>                 &lt;Col>                     &lt;ListStudents students={students} resetState={resetState} newStudent={false}\/>                 &lt;\/Col>             &lt;\/Row>             &lt;Row>                 &lt;Col>                     &lt;ModalStudent                     create={true}                     resetState={resetState}                     newStudent={true}\/>                 &lt;\/Col>             &lt;\/Row>         &lt;\/Container>     ) }  export default Home;<\/code><\/pre>\n<p>ListStudents.js \u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u043e \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u0430\u043c\u0438<\/p>\n<pre><code class=\"javascript\">import {Table} from \"reactstrap\"; import ModalStudent from \"..\/appModalStudent\/ModalStudent\"; import AppRemoveStudent from \"..\/appRemoveStudent\/appRemoveStudent\"; import ModalPhoto from \"..\/appPhotoModal\/ModalPhoto\";  const ListStudents = (props) => {     const {students} = props     return (         &lt;Table dark>             &lt;thead>             &lt;tr>                 &lt;th>Name&lt;\/th>                 &lt;th>Email&lt;\/th>                 &lt;th>Document&lt;\/th>                 &lt;th>Phone&lt;\/th>                 &lt;th>Registration&lt;\/th>                 &lt;th>Photo&lt;\/th>                 &lt;th>&lt;\/th>             &lt;\/tr>             &lt;\/thead>             &lt;tbody>             {!students || students.length &lt;= 0 ? (                 &lt;tr>                     &lt;td colSpan=\"6\" align=\"center\">                         &lt;b>\u041f\u043e\u043a\u0430 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435\u0442&lt;\/b>                     &lt;\/td>                 &lt;\/tr>             ) : students.map(student => (                     &lt;tr key={student.pk}>                         &lt;td>{student.name}&lt;\/td>                         &lt;td>{student.email}&lt;\/td>                         &lt;td>{student.document}&lt;\/td>                         &lt;td>{student.phone}&lt;\/td>                         &lt;td>{student.registrationDate}&lt;\/td>                         &lt;td>&lt;ModalPhoto                             student={student}                         \/>&lt;\/td>                         &lt;td>                             &lt;ModalStudent                                 create={false}                                 student={student}                                 resetState={props.resetState}                                 newStudent={props.newStudent}                             \/>                             &amp;nbsp;&amp;nbsp;                             &lt;AppRemoveStudent                                 pk={student.pk}                                 resetState={props.resetState}                             \/>                         &lt;\/td>                     &lt;\/tr>                 )             )}             &lt;\/tbody>         &lt;\/Table>     ) }  export default ListStudents<\/code><\/pre>\n<p>ModalStudent.js \u043c\u043e\u0434\u0430\u043b\u043a\u0430, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0430\u044f \u0437\u0430 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u0430<\/p>\n<pre><code class=\"javascript\">import {Fragment, useState} from \"react\"; import {Button, Modal, ModalHeader, ModalBody} from \"reactstrap\"; import StudentForm from \"..\/appStudentForm\/StudentForm\";  const ModalStudent = (props) => {     const [visible, setVisible] = useState(false)     var button = &lt;Button onClick={() => toggle()}>\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c&lt;\/Button>;      const toggle = () => {         setVisible(!visible)     }      if (props.create) {         button = (             &lt;Button                 color=\"primary\"                 className=\"float-right\"                 onClick={() => toggle()}                 style={{minWidth: \"200px\"}}>                 \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u0430             &lt;\/Button>         )     }     return (         &lt;Fragment>             {button}             &lt;Modal isOpen={visible} toggle={toggle}>                 &lt;ModalHeader                     style={{justifyContent: \"center\"}}>{props.create ? \"\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u0430\" : \"\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u0430\"}&lt;\/ModalHeader>                 &lt;ModalBody>                     &lt;StudentForm                         student={props.student ? props.student : []}                         resetState={props.resetState}                         toggle={toggle}                         newStudent={props.newStudent}                     \/>                 &lt;\/ModalBody>             &lt;\/Modal>         &lt;\/Fragment>     ) } export default ModalStudent; <\/code><\/pre>\n<p>ModalPhoto.js \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u0441 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c<\/p>\n<pre><code class=\"javascript\">import {Fragment, useState} from \"react\"; import {API_STATIC_MEDIA} from \"..\/..\/index\"; import {Button, Modal, ModalBody, ModalFooter, ModalHeader} from \"reactstrap\";  const ModalPhoto = (props) => {     const [visible, setVisible] = useState(false)     const toggle = () => {         setVisible(!visible)     }     return (         &lt;>             &lt;img onClick={toggle} src={API_STATIC_MEDIA + props.student.photo} alt='loading' style={{height: 50}}\/>             &lt;Modal isOpen={visible} toggle={toggle}>                 &lt;ModalHeader  style={{color:\"white\",justifyContent: \"center\", backgroundColor:\"#212529\"}}>\u0424\u043e\u0442\u043e&lt;\/ModalHeader>                 &lt;ModalBody style={{display:\"flex\", justifyContent:\"center\", backgroundColor:\"#212529\"}}>&lt;img src={API_STATIC_MEDIA + props.student.photo} alt=\"loading\"\/>&lt;\/ModalBody>                 &lt;ModalFooter style={{display:\"flex\", justifyContent:\"center\", backgroundColor:\"#212529\"}}> &lt;Button type=\"button\" onClick={() => toggle()}>\u0417\u0430\u043a\u0440\u044b\u0442\u044c&lt;\/Button>&lt;\/ModalFooter>             &lt;\/Modal>         &lt;\/>     ) }  export default ModalPhoto;<\/code><\/pre>\n<p>appRemovalStudent.js \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u0441 \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u043c \u043e\u0431 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438.<\/p>\n<pre><code class=\"javascript\">import {Fragment, useState} from \"react\"; import {Button, Modal, ModalHeader, ModalFooter} from \"reactstrap\"; import axios from \"axios\"; import {API_URL} from \"..\/..\/index\";  const AppRemoveStudent = (props) => {     const [visible, setVisible] = useState(false)     const toggle = () => {         setVisible(!visible)     }     const deleteStudent = () => {         axios.delete(API_URL + props.pk).then(() => {             props.resetState()             toggle();         });     }     return (         &lt;Fragment>             &lt;Button color=\"danger\" onClick={() => toggle()}>                 \u0423\u0434\u0430\u043b\u0438\u0442\u044c             &lt;\/Button>             &lt;Modal isOpen={visible} toggle={toggle} style={{width: \"300px\"}}>                 &lt;ModalHeader style={{justifyContent: \"center\"}}>\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b?&lt;\/ModalHeader>                 &lt;ModalFooter style={{display: \"flex\", justifyContent: \"space-between\"}}>                     &lt;Button                         type=\"button\"                         onClick={() => deleteStudent()}                         color=\"primary\"                     >\u0423\u0434\u0430\u043b\u0438\u0442\u044c&lt;\/Button>                     &lt;Button type=\"button\" onClick={() => toggle()}>\u041e\u0442\u043c\u0435\u043d\u0430&lt;\/Button>                 &lt;\/ModalFooter>             &lt;\/Modal>         &lt;\/Fragment>     ) } export default AppRemoveStudent; <\/code><\/pre>\n<p>StudentForm.js \u0444\u043e\u0440\u043c\u0430 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u0430, \u043f\u0440\u0438\u0446\u0435\u043f\u043b\u0435\u043d\u0430 \u043a \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u043e\u043a\u043d\u0443 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f\/\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/p>\n<pre><code class=\"javascript\">import {useEffect, useState} from \"react\"; import {Button, Form, FormGroup, Input, Label} from \"reactstrap\"; import axios from \"axios\"; import {API_URL} from \"..\/..\/index\";  const StudentForm = (props) => {     const [student, setStudent] = useState({})      const onChange = (e) => {         const newState = student         if (e.target.name === \"file\") {             newState[e.target.name] = e.target.files[0]         } else newState[e.target.name] = e.target.value         setStudent(newState)     }      useEffect(() => {         if (!props.newStudent) {             setStudent(student => props.student)         }         \/\/ eslint-disable-next-line     }, [props.student])      const defaultIfEmpty = value => {         return value === \"\" ? \"\" : value;     }      const submitDataEdit = async (e) => {         e.preventDefault();         \/\/ eslint-disable-next-line         const result = await axios.put(API_URL + student.pk, student, {headers: {'Content-Type': 'multipart\/form-data'}})             .then(() => {                 props.resetState()                 props.toggle()             })     }     const submitDataAdd = async (e) => {         e.preventDefault();         const data = {             name: student['name'],             email: student['email'],             document: student['document'],             phone: student['phone'],             photo: \"\/\",             file: student['file']         }         \/\/ eslint-disable-next-line         const result = await axios.post(API_URL, data, {headers: {'Content-Type': 'multipart\/form-data'}})             .then(() => {                 props.resetState()                 props.toggle()             })     }     return (         &lt;Form onSubmit={props.newStudent ? submitDataAdd : submitDataEdit}>             &lt;FormGroup>                 &lt;Label for=\"name\">Name:&lt;\/Label>                 &lt;Input                     type=\"text\"                     name=\"name\"                     onChange={onChange}                     defaultValue={defaultIfEmpty(student.name)}                 \/>             &lt;\/FormGroup>             &lt;FormGroup>                 &lt;Label for=\"email\">Email&lt;\/Label>                 &lt;Input                     type=\"email\"                     name=\"email\"                     onChange={onChange}                     defaultValue={defaultIfEmpty(student.email)}                 \/>             &lt;\/FormGroup>             &lt;FormGroup>                 &lt;Label for=\"document\">Document:&lt;\/Label>                 &lt;Input                     type=\"text\"                     name=\"document\"                     onChange={onChange}                     defaultValue={defaultIfEmpty(student.document)}                 \/>             &lt;\/FormGroup>             &lt;FormGroup>                 &lt;Label for=\"phone\">Phone:&lt;\/Label>                 &lt;Input                     type=\"text\"                     name=\"phone\"                     onChange={onChange}                     defaultValue={defaultIfEmpty(student.phone)}                 \/>             &lt;\/FormGroup>             &lt;FormGroup>                 &lt;Label for=\"photo\">Photo:&lt;\/Label>                 &lt;Input                     type=\"file\"                     name=\"file\"                     onChange={onChange}                     accept='image\/*'                 \/>             &lt;\/FormGroup>             &lt;div style={{display: \"flex\", justifyContent: \"space-between\"}}>                 &lt;Button>Send&lt;\/Button> &lt;Button onClick={props.toggle}>Cancel&lt;\/Button>             &lt;\/div>         &lt;\/Form>     ) }  export default StudentForm; <\/code><\/pre>\n<p>\u041f\u043e\u0434\u043f\u0440\u0430\u0432\u0438\u043c \u0442\u0430\u043a \u0436\u0435 index.js<\/p>\n<pre><code class=\"javascript\">import React from 'react'; import ReactDOM from 'react-dom\/client'; import '.\/index.css'; import App from '.\/components\/app\/App'; import reportWebVitals from '.\/reportWebVitals'; import 'bootstrap\/dist\/css\/bootstrap.min.css'  export const API_URL = \"http:\/\/127.0.0.1:8000\/api\/students\/\" export const API_STATIC_MEDIA = \"http:\/\/127.0.0.1:8000\/\"  const root = ReactDOM.createRoot(document.getElementById('root')); root.render(     &lt;React.StrictMode>         &lt;App\/>     &lt;\/React.StrictMode> );  reportWebVitals();<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0431\u0435\u0433\u0438\u0442\u0435\u0441\u044c \u043f\u043e \u043f\u0443\u0442\u044f\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u043e\u0432, \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0451 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u043b\u043e \u0441 \u0432\u0430\u0448\u0435\u0439 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0435\u0439, \u0435\u0441\u043b\u0438 \u0432\u044b \u043d\u0430\u0437\u0432\u0430\u043b\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043a\u0430\u043a-\u0442\u043e \u0438\u043d\u0430\u0447\u0435.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 <code>npm start<\/code> \u0438\u0438\u0438&#8230;<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fe0\/cda\/a7c\/fe0cdaa7c024000bf36bb8a82b8b5a82.png\" width=\"488\" height=\"255\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fe0\/cda\/a7c\/fe0cdaa7c024000bf36bb8a82b8b5a82.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0422\u043e\u043f\u0430\u0435\u043c \u043d\u0430 <code>http:\/\/localhost:3000<\/code><\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/814\/aaa\/7b7\/814aaa7b7aa44d29dc9e6612f7d4de9e.png\" width=\"1617\" height=\"985\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/814\/aaa\/7b7\/814aaa7b7aa44d29dc9e6612f7d4de9e.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u043c \u043d\u0430\u0448\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0433\u0440\u0443\u0437\u0438\u043b\u0438\u0441\u044c. \u041a\u0430\u0440\u0442\u0438\u043d\u043e\u043a \u043d\u0435\u0442, \u043d\u043e \u044d\u0442\u043e \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043c\u044b \u0435\u0451 \u043d\u0435 \u043f\u043e\u043b\u043e\u0436\u0438\u043b\u0438 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 \u0441 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c django \u043f\u0430\u0440\u0443 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u043e\u0432 \u0438 \u0444\u0430\u0439\u043b nophoto.png \u0434\u043b\u044f \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u043e\u0439 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0438<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a21\/dfc\/768\/a21dfc768759efe3c9b6fee074c4de4b.png\" width=\"214\" height=\"282\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a21\/dfc\/768\/a21dfc768759efe3c9b6fee074c4de4b.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1d9\/3ab\/b9e\/1d93abb9e9d5e3e8188ba17a20094aa5.png\" alt=\"\u041f\u043e\u0441\u043b\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u0438\u0434\u0438\u043c \u0447\u0442\u043e \u0432\u0441\u0451 \u043e\u043a!\" title=\"\u041f\u043e\u0441\u043b\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u0438\u0434\u0438\u043c \u0447\u0442\u043e \u0432\u0441\u0451 \u043e\u043a!\" width=\"1476\" height=\"809\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1d9\/3ab\/b9e\/1d93abb9e9d5e3e8188ba17a20094aa5.png\"\/><figcaption>\u041f\u043e\u0441\u043b\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u0438\u0434\u0438\u043c \u0447\u0442\u043e \u0432\u0441\u0451 \u043e\u043a!<\/figcaption><\/figure>\n<p>\u0412 \u0446\u0435\u043b\u043e\u043c, \u044d\u0442\u043e \u0443\u0436\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0435\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c\/\u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0438 \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u041d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430, \u043e\u043d\u0430 \u0443\u0445\u043e\u0434\u0438\u0442 \u043d\u0430 django, \u043d\u043e \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0430\u043c. <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0440\u0435\u043c\u044f \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435. \u041d\u043e \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441 \u043d\u0438\u043c \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043f\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u0438\u0442\u044c, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u043b\u043e\u0441\u044c \u0447\u0442\u043e \u044d\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0431\u0440\u043e\u043a\u0435\u0440\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. RabbitMQ \u043c\u044b \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435. \u041d\u043e \u0442\u043e\u0433\u0434\u0430 \u0443\u0436\u0435 \u0438 \u043f\u0443\u0441\u0442\u044c \u0441\u0430\u043c\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0435\u0437\u0436\u0430\u0435\u0442. <\/p>\n<p>\u0414\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0443 \u043c\u0435\u043d\u044f \u0440\u0430\u0437\u0432\u0451\u0440\u043d\u0443\u0442\u0430 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u0430\u0448\u0438\u043d\u0430 \u043d\u0430 Centos 7 \u043d\u0430 VirtualBox.<\/p>\n<p>\u0412 \u0446\u0435\u043b\u043e\u043c \u041e\u0421 \u043d\u0435 \u0432\u0430\u0436\u043d\u0430, \u0442.\u043a. \u0434\u043e\u043a\u0435\u0440 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043b\u044e\u0431\u0443\u044e \u0443\u0434\u043e\u0431\u043d\u0443\u044e \u0434\u043b\u044f \u0432\u0430\u0441 \u041e\u0421, Fedora\/Ubuntu\/Debian \u0438 \u0434\u0430\u0436\u0435 \u043d\u0430 windows (\u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435 \u043d\u0430\u0434\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c wsl).<\/p>\n<p>\u0414\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e vs code, \u0432 \u043d\u0435\u0439 \u0435\u0441\u0442\u044c \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0434\u0435\u043f\u043b\u043e\u044f \u043f\u043e sftp. \u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 pycharm \u0442\u043e \u0442\u0430\u043c \u0442\u043e\u0436\u0435 \u0432\u0441\u0451 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f. \u0422\u0430\u043a \u0438\u043b\u0438 \u0438\u043d\u0430\u0447\u0435, \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044e \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 ProjectStudent \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c (\u043b\u0443\u0447\u0448\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0438\u0437 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0438 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f env \u0443 django \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 node_modules \u0443 \u0440\u0435\u0430\u043a\u0442, \u043f\u043e\u043c\u0435\u0448\u0430\u0442\u044c \u043e\u043d\u0438 \u043d\u0435 \u043f\u043e\u043c\u0435\u0448\u0430\u044e\u0442, \u043d\u043e \u0442\u0430\u043c \u043a\u0443\u0447\u0430 \u0444\u0430\u0439\u043b\u043e\u0432, \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043e\u043d\u0438 \u0434\u043e\u043b\u0433\u043e, \u0430 \u0442\u043e\u043b\u043a\u0443 \u043e\u0442 \u043d\u0438\u0445 \u0442\u0430\u043c \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e, \u043c\u0435\u0440\u0442\u0432\u044b\u0439 \u0433\u0440\u0443\u0437.)<\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 Django.<\/p>\n<p>\u041e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u0434\u0435\u043b\u0430\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>pip freeze >requirements.txt<\/code><\/p>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 <code>django\\django_project\\django_project.<\/code><\/p>\n<p>\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0442\u0430\u043c <code>Dockerfile<\/code><\/p>\n<p>\u0417\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u0435\u0433\u043e<\/p>\n<pre><code class=\"yaml\"># \u0421\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0437 FROM python:3.11-alpine  # \u0440\u0430\u0431\u043e\u0447\u0430\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f WORKDIR \/usr\/src\/app RUN mkdir -p $WORKDIR\/static RUN mkdir -p $WORKDIR\/media  # \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f python #\u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u043a\u044d\u0448\u0430 .pyc ENV PYTHONDONTWRITEBYTECODE 1 # \u043d\u0435 \u043f\u043e\u043c\u0435\u0449\u0430\u0442\u044c \u0432 \u0431\u0443\u0444\u0435\u0440 \u043f\u043e\u0442\u043e\u043a\u0438 stdout \u0438 stderr ENV PYTHONUNBUFFERED 1  # \u043e\u0431\u043d\u043e\u0432\u0438\u043c pip RUN pip install --upgrade pip  # \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438. \u044d\u0442\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0437\u0430\u043a\u0435\u0448\u0438\u0440\u0443\u0435\u0442\u0441\u044f  # \u0438 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 requirements.txt COPY .\/requirements.txt . RUN pip install -r requirements.txt  # \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u0451 \u0447\u0442\u043e \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c. COPY . .<\/code><\/pre>\n<p>\u0421 Django \u043f\u043e\u043a\u0430 \u0432\u0441\u0451. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u043a react.<\/p>\n<p>\u0422\u0430\u043a \u0436\u0435, \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 reactapp \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c Dockerfile<\/p>\n<pre><code class=\"yaml\"># \u0442\u0430\u043a \u0436\u0435 \u0431\u0435\u0440\u0451\u043c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441 node \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 alpine FROM node:18-alpine as build # \u0417\u0430\u0434\u0430\u0435\u043c \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 WORKDIR \/usr\/src\/app # \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0442\u0443\u0434\u0430 \u043d\u0430\u0448\u0438 json \u0444\u0430\u0439\u043b\u044b ADD *.json .\/ # \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0432\u0441\u0435 \u043f\u0430\u043a\u0435\u0442\u044b \u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0432 json RUN npm install  # \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0438 public \u0438 src.  # \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 COPY . . \u043d\u043e \u0435\u0441\u043b\u0438 \u0432\u044b \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b\u0438 node_modules, # \u0442\u043e \u0431\u0443\u0434\u0435\u0442\u0435 \u0436\u0434\u0430\u0442\u044c \u043f\u043e\u043a\u0430 \u0437\u0430\u043b\u044c\u0451\u0442\u0441\u044f \u044d\u0442\u043e\u0442 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0446\u0435\u043b\u0438\u043a\u043e\u043c.  # \u0434\u0430 \u0438 \u043f\u043e\u0442\u043e\u043c \u043c\u043e\u0433\u0443\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. ADD .\/public .\/public ADD .\/src .\/src<\/code><\/pre>\n<p>\u0418\u0442\u0430\u043a, \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0431\u043e\u0440\u043a\u0438 \u0434\u0432\u0443\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0433\u043e\u0442\u043e\u0432\u043e. \u041d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0438\u0445 \u0440\u0443\u043a\u0430\u043c\u0438 \u043d\u0435 \u0442\u0430\u043a \u0443\u0434\u043e\u0431\u043d\u043e, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u0443\u0441\u0442\u044c \u044d\u0442\u0438\u043c \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f docker-compose. \u0422\u0430\u043a \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0432\u044b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u043a\u0435\u0440, \u0442\u043e \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0435\u0449\u0435 docker-compose.<\/p>\n<p>\u0412\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 ProjectStudent \u0438 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0442\u0430\u043c <code>docker-compose.yml<\/code><\/p>\n<pre><code class=\"yaml\">version: '3.8' # \u041f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u043c \u0434\u0432\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u0430, django \u0418 node services:   django:     #\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u0447\u0442\u043e build \u0431\u0443\u0434\u0435\u0442 \u0438\u0437 dockerfile \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f .\/django\/django_project\/     build: .\/django\/django_project\/     # \u0438\u043c\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430     container_name: djangoapp     # \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u043f\u0440\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u043b\u0438 \u043f\u0440\u0438 \u0430\u0432\u0430\u0440\u0438\u0439\u043d\u043e\u043c \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438     restart: always     # \u043f\u0440\u043e\u0431\u0440\u043e\u0441 \u043f\u043e\u0440\u0442\u043e\u0432 \u0432\u043d\u0443\u0442\u0440\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430, 8000 \u043f\u043e\u0440\u0442 \u043d\u0430 \u0445\u043e\u0441\u0442 \u043c\u0430\u0448\u0438\u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0431\u0440\u043e\u0448\u0435\u043d \u0432\u043d\u0443\u0442\u0440\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u043d\u0430 \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 8000 \u043f\u043e\u0440\u0442     ports:       - 8000:8000     # \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430     command: >       sh -c \"python manage.py runserver 0.0.0.0:8000\"     # \u0414\u043b\u044f \u0441\u0442\u0430\u0442\u0438\u043a\u0438 \u043c\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0434\u0432\u0430 volume (\u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043d\u0430\u0448\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0435 \u043f\u0440\u043e\u043f\u0430\u0434\u0430\u043b\u0438)), \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0438\u0445 \u043d\u0438\u0436\u0435.     volumes:       - django_static_volume:\/usr\/src\/app\/static       - django_media_volume:\/usr\/src\/app\/media     # \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043a \u0441\u0435\u0442\u0438 myNetwork (\u0432 \u0446\u0435\u043b\u043e\u043c \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u043e \u0434\u043e \u043a\u0443\u0447\u0438 \u0447\u0442\u043e\u0431 \u0431\u044b\u043b\u043e)     networks:       - myNetwork    node:     # \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e, build \u0438\u0437 .\/reactapp\/dockerfile     build: .\/reactapp     # \u0438\u043c\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430     container_name: reactapp     # \u0440\u0435\u0441\u0442\u0430\u0440\u0442     restart: always     # \u043f\u043e\u0440\u0442\u044b     ports:       - 3000:3000     # \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435     command: npm start     # \u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c. \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430 \u043d\u043e\u0434\u0435, \u0435\u0441\u043b\u0438 \u043d\u0435\u043a\u043e\u043c\u0443 \u043e\u0442\u0434\u0430\u0442\u044c \u0435\u0439 \u0434\u0430\u043d\u043d\u044b\u0435. \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u043c \u0441\u0435\u0440\u0432\u0438\u0441 django, \u0430 \u0437\u0430 \u043d\u0435\u0439 node     depends_on:       - django     # \u0421\u0435\u0442\u044c \u0442\u0430 \u0436\u0435, \u0432\u0441\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043a\u0440\u0443\u0442\u0438\u0442\u044c\u0441\u044f \u0432 \u043e\u0434\u043d\u0439\u043e \u0441\u0435\u0442\u0438 \u0447\u0442\u043e\u0431\u044b \u0432\u0438\u0434\u0435\u0442\u044c \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0430.     networks:       - myNetwork # \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0434\u0432\u0430 volume \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u0438\u043a\u0438 volumes:   django_static_volume:   django_media_volume:<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u044b\u0435 \u0434\u0432\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0433\u043e\u0442\u043e\u0432\u044b. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c <code>docker-compose up<\/code><\/p>\n<pre><code class=\"css\">.... djangoapp | January 23, 2023 - 08:45:29 djangoapp | Django version 4.1.5, using settings 'django_project.settings' djangoapp | Starting development server at http:\/\/0.0.0.0:8000\/ djangoapp | Quit the server with CONTROL-C. .... reactapp  | Compiled successfully! reactapp  | reactapp  | You can now view reactapp in the browser. reactapp  | reactapp  |   Local:            http:\/\/localhost:3000 reactapp  |   On Your Network:  http:\/\/192.168.224.3:3000<\/code><\/pre>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0432\u0441\u0451 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u043e\u0441\u044c.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c.<\/p>\n<p>\u0422.\u043a. \u0442\u0435\u043f\u0435\u0440\u044c \u043e\u043d\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u043d\u0430 \u0445\u043e\u0441\u0442\u043e\u0432\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u0435, localhost:3000 \u0443\u0436\u0435 \u043d\u0435 \u043a\u0430\u0442\u0438\u0442, \u043d\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0438 \u043f\u0440\u043e\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u043b\u0438 \u043f\u043e\u0440\u0442\u044b, \u0438\u0434\u0451\u043c \u043d\u0430 \u0445\u043e\u0441\u0442\u043e\u0432\u0443\u044e \u043c\u0430\u0448\u0438\u043d\u0443 \u043d\u0430 3000 \u043f\u043e\u0440\u0442. \u0412 \u043c\u043e\u0451\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e <code>http:\/\/192.168.56.101:3000\/<\/code><\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ed5\/9d6\/709\/ed59d670978dd238a0cafa4d65f306b3.png\" width=\"1233\" height=\"347\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ed5\/9d6\/709\/ed59d670978dd238a0cafa4d65f306b3.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0412\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0440\u0435\u0430\u043a\u0442 \u0437\u0430\u043f\u0443\u0449\u0435\u043d, \u043d\u043e \u0432\u043e\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0435\u0442. \u042d\u0442\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 API \u0432\u0441\u0451 \u0435\u0449\u0435 \u0432\u0435\u0434\u0451\u0442 \u043d\u0430 <code>127.0.0.1:8000<\/code><\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u043c. \u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u0432\u0441\u0451, \u0447\u0435\u0440\u0435\u0437 ctrl+C<\/p>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c <code>reactapp\\src\\index.js<\/code><\/p>\n<p>\u0418 \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u043c \u043f\u0443\u0442\u044c \u0434\u043e api<\/p>\n<p><code>export const API_URL = \"http:\/\/192.168.56.101:8000\/api\/students\/\"<\/code><\/p>\n<p>\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0438\u0440\u0443\u0435\u043c, \u0438 \u0447\u0442\u043e\u0431\u044b \u0447\u0430\u0441\u0442\u043e \u043d\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c src \u0438 public \u043a\u0430\u043a volume \u043a \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0443, \u0442\u043e\u0433\u0434\u0430 \u0432\u0441\u0435 \u0432\u0430\u0448\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u043f\u0430\u0434\u0430\u0442\u044c \u043d\u0430 \u0445\u043e\u0441\u0442\u043e\u0432\u0443\u044e \u043c\u0430\u0448\u0438\u043d\u0443 \u0438 \u0442.\u043a. \u044d\u0442\u0438 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u043a\u0430\u043a volume \u0442\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u0441\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u0440\u0430\u0437\u0443 \u043e\u0442\u0440\u0430\u0436\u0430\u044e\u0442\u0441\u044f \u0438 \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435.<\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0432 docker-compose.yml \u0432 \u0441\u0435\u0440\u0432\u0438\u0441 node \u043f\u0430\u0440\u0443 \u0441\u0442\u0440\u043e\u043a<\/p>\n<pre><code class=\"yaml\">\u00a0 \u00a0 volumes: \u00a0 \u00a0 \u00a0 - .\/reactapp\/public\/:\/usr\/src\/app\/public\/ \u00a0 \u00a0 \u00a0 - .\/reactapp\/src\/:\/usr\/src\/app\/src\/<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0443\u044e \u0436\u0435 \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0438 \u0441 django\u00a0<\/p>\n<pre><code class=\"yaml\">\u00a0 \u00a0 volumes: \u00a0 \u00a0 \u00a0 - .\/django\/django_project:\/usr\/src\/app\/ \u00a0 \u00a0 \u00a0 - django_static_volume:\/usr\/src\/app\/static \u00a0 \u00a0 \u00a0 - django_media_volume:\/usr\/src\/app\/media<\/code><\/pre>\n<p>\u0412\u0441\u0435, \u0441\u043d\u043e\u0432\u0430 \u0434\u0435\u043b\u0430\u0435\u043c docker-compose up.<\/p>\n<p>\u0414\u043e\u0436\u0438\u0434\u0430\u0435\u043c\u0441\u044f \u043f\u043e\u043a\u0430 \u043b\u043e\u0433 \u0440\u0435\u0430\u043a\u0442\u0430 \u043d\u0435 \u043d\u0430\u043f\u0438\u0448\u0435\u0442 successfully! \u0418 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0435\u0449\u0451 \u0440\u0430\u0437.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5eb\/048\/f5b\/5eb048f5b101c38edb90ffc9cc8e2585.png\" width=\"1277\" height=\"776\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5eb\/048\/f5b\/5eb048f5b101c38edb90ffc9cc8e2585.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u043c\u0435\u0441\u0442\u0435. \u041d\u0430\u0441\u0442\u0430\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u0434\u043b\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439. <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u043e\u0442\u0445\u043e\u0434\u0438\u0442\u044c \u0434\u0430\u043b\u0435\u043a\u043e \u043e\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432, \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0440\u0430\u0437\u0443 rabbit. \u041e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0432\u0441\u0451 \u0447\u0435\u0440\u0435\u0437 <code>ctrl + C<\/code><\/p>\n<p>\u0421\u043d\u043e\u0432\u0430 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c yml \u0444\u0430\u0439\u043b \u0438 \u0434\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0441\u0435\u0440\u0432\u0438\u0441 rmq<\/p>\n<pre><code class=\"yaml\">rmq:     # \u043d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u043c\u044b \u043d\u0435 \u0431\u0438\u043b\u0434\u0438\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0438\u0437 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f     image: rabbitmq:3.10-management     restart: always     container_name: rmq     networks:       - myNetwork     # \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438.      environment:       - RABBITMQ_DEFAULT_USER=admin       - RABBITMQ_DEFAULT_PASS=admin     # volume \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 rmq, \u043c\u043e\u0436\u043d\u043e \u0438 \u0431\u0435\u0437 \u043d\u0435\u0433\u043e, \u043d\u043e \u0442\u043e\u0433\u0434\u0430 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u0438 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u0442\u0438\u0445\u043e\u043d\u044c\u043a\u0443 \u043d\u0430\u043a\u0430\u043f\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f     volumes:       - rabbitmq_data_volume:\/var\/lib\/rabbitmq\/     # \u043f\u0440\u043e\u0431\u0440\u043e\u0441 \u043f\u043e\u0440\u0442\u043e\u0432, 15672 \u0434\u043b\u044f \u043c\u0435\u043d\u0435\u0434\u0436\u043c\u0435\u043d\u0442\u0430, 5671-5672 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b     ports:       - 1234:15672       - 5671-5672:5671-5672     <\/code><\/pre>\n<p>\u0418 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 volume \u0432 \u0441\u043f\u0438\u0441\u043e\u043a volumes<\/p>\n<pre><code class=\"yaml\">volumes:   django_static_volume:   django_media_volume:   rabbitmq_data_volume:<\/code><\/pre>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e.<\/p>\n<p>\u041e\u0442 \u0440\u0435\u0430\u043a\u0442\u0430 \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0433\u043e \u043d\u0435 \u0442\u0440\u043e\u0433\u0430\u0435\u043c. <\/p>\n<p>\u0418\u0434\u0435\u043c \u043f\u0440\u0430\u0432\u0438\u0442\u044c django<\/p>\n<p>\u041d\u0430\u0434\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0430\u0440\u0443 \u043d\u043e\u0432\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438 \u0447\u0443\u0442\u044c \u0434\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0435.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u0432 \u0444\u0430\u0439\u043b <code>django\\django_project\\students\\views.py<\/code><\/p>\n<p>\u0414\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"python\">def save_image_to_media(serializer, request):     file_name = send_to_rabbit(request).split('separator')[1]     file_path = 'media\\\\photo\\\\' + file_name     serializer.validated_data['photo'] = file_path     if serializer.is_valid():         serializer.save()<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 request \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e send_to_rabbit, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0438\u043c\u044f \u0444\u0430\u0439\u043b\u0430, \u044d\u0442\u043e \u0438\u043c\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0411\u0414.<\/p>\n<pre><code class=\"python\">def send_to_rabbit(data):     file = data.FILES['file']     file_name = bytes('separator' + str(uuid.uuid4()) + '.' + file.name[file.name.rfind(\".\") + 1:], 'utf-8')     img = file.read() + file_name     hostname = '192.168.56.101'     port = 5672     credentials = pika.PlainCredentials(username='admin', password='admin')     parameters = pika.ConnectionParameters(host=hostname, port=port, credentials=credentials)     connection = pika.BlockingConnection(parameters=parameters)     channel = connection.channel()     channel.queue_declare(queue='to_resize')     channel.basic_publish(exchange='',                           routing_key='to_resize',                           body=img)     connection.close()     return file_name.decode('utf-8')<\/code><\/pre>\n<p>\u0422\u0443\u0442 \u0443 \u043d\u0430\u0441 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<p>1)\u00a0\u00a0\u00a0\u00a0 \u0418\u0437 request \u0432\u044b\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0435 file, \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u0431\u0430\u0439\u0442\u043e\u0432\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432, \u043a \u043d\u0435\u043c\u0443 \u0447\u0435\u0440\u0435\u0437 \u0441\u0435\u043f\u0430\u0440\u0430\u0442\u043e\u0440 \u043f\u0440\u0438\u0446\u0435\u043f\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0447\u0435\u0440\u0435\u0437 uuid \u0438\u043c\u044f \u044d\u0442\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430.<\/p>\n<p>2)\u00a0\u00a0\u00a0\u00a0 \u041f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043d\u0430 rmq.<\/p>\n<p>\u0414\u0430, \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f admin\/admin, \u043c\u043e\u0436\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u043b\u044e\u0431\u043e\u0433\u043e \u0434\u0440\u0443\u0433\u043e\u0433\u043e, \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0434\u043e \u0434\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c.<\/p>\n<p>3)\u00a0\u00a0\u00a0\u00a0 \u0418\u043c\u044f \u0444\u0430\u0439\u043b\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e, \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0411\u0414.<\/p>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u0435\u0433\u043e \u043d\u0430\u0434\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u044c.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0432 \u043a\u043e\u0440\u043d\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 worker.py<\/p>\n<p>\u041f\u043e \u0438\u0434\u0435\u0435 \u044d\u0442\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441, \u043d\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0439 \u0441 django. \u041d\u043e \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u043b\u043e\u0434\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435, \u043f\u0443\u0441\u0442\u044c \u0432\u0441\u0435 \u0432 \u043e\u0434\u043d\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442, \u043b\u043e\u0433\u0438\u043a\u0443 \u044d\u0442\u043e \u043d\u0435 \u043d\u0430\u0440\u0443\u0448\u0438\u0442.<\/p>\n<p><code>Worker.py<\/code><\/p>\n<pre><code class=\"python\">import pika from PIL import Image import io import time  def initial():     try:         hostname = 'rmq'         port = 5672         credentials = pika.PlainCredentials(username='admin', password='admin')         parameters = pika.ConnectionParameters(host=hostname, port=port, credentials=credentials)         connection = pika.BlockingConnection(parameters=parameters)         # \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u0430\u043d\u0430\u043b         channel = connection.channel()         # \u041d\u0430 \u0432\u0441\u044f\u043a\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043e\u0447\u0435\u0440\u0435\u0434\u0438         channel.queue_declare(queue='to_resize')         channel.queue_declare(queue='from_resize')         channel.basic_consume(queue='to_resize',                       auto_ack=True,                       on_message_callback=callback)          return True, channel     except:         return False, None  def callback(ch, method, properties, body):     try:         data = body.split(b'separator')         file_name = b'separator' + data[1]         fixed_height = 300         image = Image.open(io.BytesIO(data[0]))         height_percent = (fixed_height \/ float(image.size[1]))         width_size = int((float(image.size[0]) * float(height_percent)))         new = image.resize((width_size, fixed_height))         img_width = bytes(f'separator{new.width}', 'utf-8')         img_height = bytes(f'separator{new.height}', 'utf-8')         tobyte = new.tobytes() + img_width + img_height + file_name         return_resize_image(tobyte)     except Exception as error:         print(error)  def return_resize_image(data):     channel.basic_publish(exchange='',                           routing_key='from_resize',                           body=data)  if __name__ == '__main__':     count_try=0     conn=False     while not conn:         count_try+=1         print(f'I`m WORKER. \u041f\u043e\u043f\u044b\u0442\u043a\u0430 \u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u0441\u044f \u2116{count_try}')         conn, channel=initial()           if not conn:             time.sleep(2)       print(' [*] I`m WORKER and i`m Waiting for messages. To exit press CTRL+C')     channel.start_consuming() <\/code><\/pre>\n<p>\u0427\u0442\u043e \u0442\u0443\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442.<\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435 worker \u0432 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u044c\u0441\u044f \u043a rabbit, \u043f\u0440\u0438 \u043d\u0435\u0443\u0434\u0430\u0447\u0435 \u0441\u043f\u0438\u0442 2 \u0441\u0435\u043a\u0443\u043d\u0434\u044b \u0438 \u0441\u043d\u043e\u0432\u0430 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f. <\/p>\n<p>\u0412 initial() \u043f\u043e\u043c\u0438\u043c\u043e \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d\u0430 callback \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0447\u0442\u043e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c.<\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043c\u0430\u0441\u0441\u0438\u0432 \u0447\u0435\u0440\u0435\u0437 separator \u0447\u0430\u0441\u0442\u044c \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0431\u044a\u0435\u043a\u0442 Image, \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043c\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 pillow. \u0414\u0430\u043b\u044c\u0448\u0435 \u043e\u043d\u043e \u043f\u0440\u043e\u043f\u043e\u0440\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e \u0440\u0435\u0441\u0430\u0439\u0437\u0438\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0441\u043e\u0442\u0430 \u0431\u044b\u043b\u0430 \u043d\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 300 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439.<\/p>\n<p>\u0421\u043d\u043e\u0432\u0430 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u0431\u0430\u0439\u0442\u043e\u0432\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432, \u0442\u0430\u043a \u0436\u0435 \u0447\u0435\u0440\u0435\u0437 \u0441\u0435\u043f\u0430\u0440\u0430\u0442\u043e\u0440\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u043c\u0435\u0440 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438 \u0438\u043c\u044f \u0444\u0430\u0439\u043b\u0430 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0443\u0436\u0435 \u0432 \u0434\u0440\u0443\u0433\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c. \u0414\u043b\u044f \u0443\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u043d\u0438\u044f \u0432 \u043d\u0443\u0436\u043d\u044b\u0439 \u043a\u0430\u0442\u0430\u043b\u043e\u0433. \u0420\u0430\u0437\u043c\u0435\u0440 \u043d\u0443\u0436\u0435\u043d \u0447\u0442\u043e\u0431\u044b \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 pillow \u0441\u043d\u043e\u0432\u0430 \u043c\u043e\u0433\u043b\u0430 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0435\u0433\u043e \u0438\u0437 \u0431\u0430\u0439\u0442\u043e\u0432\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0432 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435. (\u0441\u043f\u043e\u0441\u043e\u0431 \u0447\u0435\u0440\u0435\u0437 \u0441\u0435\u043f\u0430\u0440\u0430\u0442\u043e\u0440\u044b \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u0439, \u044f \u043f\u043e\u043d\u0438\u043c\u0430\u044e, \u043d\u043e \u0447\u0435\u0442 \u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e \u0432 \u0433\u043e\u043b\u043e\u0432\u0443 \u043d\u0438\u0447\u0435\u0433\u043e \u043b\u0443\u0447\u0448\u0435. \u041d\u043e \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.)<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0442\u043e\u0440\u043e\u0439 \u0432\u043e\u0440\u043a\u0435\u0440.<\/p>\n<p>\u0422\u0443\u0442 \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u043c\u043e\u043c\u0435\u043d\u0442. \u0422\u0430\u043a \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435 \u043b\u0443\u0447\u0448\u0435 \u043d\u0435 \u0434\u0435\u043b\u0430\u0442\u044c. <\/p>\n<p>\u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u044f \u0445\u043e\u0442\u0435\u043b, \u0447\u0442\u043e\u0431\u044b \u0432\u0442\u043e\u0440\u043e\u0439 \u0432\u043e\u0440\u043a\u0435\u0440 \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0432 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0431\u043b\u0438\u0437\u043e\u0441\u0442\u0438 \u0441 django \u0438 \u0443\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u043b \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u0430\u0439\u043b \u043d\u0430 \u043c\u0435\u0441\u0442\u043e, \u043d\u043e \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u043b \u0411\u0414 \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044f \u0438\u043c\u044f \u0438 \u043f\u0443\u0442\u044c \u043a \u0444\u0430\u0439\u043b\u0443 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0435 \u043f\u043e\u043b\u0435 \u043c\u043e\u0434\u0435\u043b\u0438. \u0412 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u043b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043a\u0430\u043a \u0441\u0435\u0440\u0432\u0438\u0441, \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u0437\u0430\u043f\u0443\u0449\u0435\u043d django \u0441\u0435\u0440\u0432\u0435\u0440 \u0438\u043b\u0438 \u043d\u0435\u0442. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u044b\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0430 \u0442\u0430\u043a\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5bf\/fbc\/13c\/5bffbc13c23cde2f7a33f95f95bc8d07.png\" width=\"276\" height=\"301\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5bf\/fbc\/13c\/5bffbc13c23cde2f7a33f95f95bc8d07.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0447\u0435\u0440\u0435\u0437 python manage.py my_command \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u043b\u0441\u044f worker. \u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438 \u043e\u0442 \u0438\u0434\u0435\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0411\u0414 \u0438\u0437 worker \u044f \u043e\u0442\u043a\u0430\u0437\u0430\u043b\u0441\u044f, \u0438 \u043e\u043d \u0441\u0442\u0430\u043b \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u043f\u043e \u043d\u0443\u0436\u043d\u043e\u043c\u0443 \u043c\u043d\u0435 \u043f\u0443\u0442\u0438. \u0422\u0430\u043a \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e worker2 \u0440\u044f\u0434\u043e\u043c \u0441 \u043f\u0435\u0440\u0432\u044b\u043c \u0438 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0432 \u043d\u0435\u0433\u043e. \u041d\u043e \u044f \u0443\u0436\u0435 \u043d\u0435 \u0441\u0442\u0430\u043b.<\/p>\n<p>\u0422\u0430\u043a \u0447\u0442\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u043a\u0430\u043a \u0435\u0441\u0442\u044c.<\/p>\n<p><code>my_command.py<\/code><\/p>\n<pre><code class=\"python\">from django.core.management.base import BaseCommand from PIL import Image import pika import time  class Command(BaseCommand):     def handle(self, *args, **options):         count_try=0         conn=False         while not conn:             count_try+=1             print(f'I`m DJANGO WORKER. \u041f\u043e\u043f\u044b\u0442\u043a\u0430 \u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u0441\u044f \u2116{count_try}')             conn, channel=self.initial()             if not conn:                 time.sleep(2)         print(' [*] I`m DJANGO WORKER and i`m Waiting for messages. To exit press CTRL+C')         channel.start_consuming()      def initial(self):         try:             hostname = 'rmq'             port = 5672             credentials = pika.PlainCredentials(username='admin', password='admin')             parameters = pika.ConnectionParameters(host=hostname, port=port, credentials=credentials)             connection = pika.BlockingConnection(parameters=parameters)             # \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u0430\u043d\u0430\u043b             channel = connection.channel()             channel.queue_declare(queue='to_resize')             channel.queue_declare(queue='from_resize')             try:                 channel.basic_consume(queue='from_resize',                                 auto_ack=True,                                 on_message_callback=self.callback)             except Exception as error:                 print(error)             return True, channel         except:             return False, None      @staticmethod     def callback(ch, method, properties, body):         try:             data = body.split(b'separator')             image = Image.frombytes(\"RGB\", (int(data[1]), int(data[2])), data[0])             file_name = data[3].decode('UTF-8')             image.save('media\/photo\/' + file_name)         except Exception as error:             print(error)<\/code><\/pre>\n<p>\u0422\u0443\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u044c\u0441\u044f \u0438 callback \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. <\/p>\n<p>\u0412 callback \u0442\u0435\u043b\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043f\u0438\u043b\u0438\u0442\u0441\u044f \u043f\u043e \u0441\u0435\u043f\u0430\u0440\u0430\u0442\u043e\u0440\u0443, \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u0438\u0437 \u0431\u0430\u0439\u0442\u043e\u0432\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0432 Image \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0412 \u0446\u0435\u043b\u043e\u043c \u0432\u0441\u0451 \u0445\u043e\u0440\u043e\u0448\u043e, \u043d\u043e \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u043e\u0432 \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a.<\/p>\n<p>\u043d\u0430\u0434\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0438\u0445 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 <code>requirements<\/code><\/p>\n<p><code>pip install pika uuid pillow<\/code><\/p>\n<p><code>pip freeze >requirements.txt<\/code><\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0437\u0430\u043f\u0443\u0441\u043a \u043d\u0430\u0448\u0438\u0445 worker\u2019\u043e\u0432 \u0432 yml \u0444\u0430\u0439\u043b\u0435.<\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 django<\/p>\n<pre><code class=\"yaml\">    command: >       sh -c \"nohup python worker.py &amp; nohup python manage.py my_command &amp; python manage.py runserver 0.0.0.0:8000\"<\/code><\/pre>\n<p>\u0442\u0430\u043a \u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 django \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 rmq, \u0432\u0435\u0434\u044c \u0435\u043c\u0443 \u043d\u0430\u0434\u043e \u043a\u0443\u0434\u0430-\u0442\u043e \u0441\u043b\u0430\u0442\u044c \u0438 \u043e\u0442\u043a\u0443\u0434\u0430-\u0442\u043e \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/p>\n<pre><code class=\"yaml\">depends_on:       - rmq<\/code><\/pre>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0443 \u043d\u0430\u0441 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f requirements \u043d\u0430\u0434\u043e \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 django<\/p>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <\/p>\n<p><code>docker-compose up -d --build<\/code><\/p>\n<p>&#8212;build \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0435\u0440\u0451\u0442 \u0432\u0441\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0443 react \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u043e\u0441\u044c, \u043e\u043d \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u0434\u0442\u044f\u043d\u0435\u0442\u0441\u044f \u0438\u0437 \u043a\u044d\u0448\u0430, django \u0436\u0435 \u0432\u043e\u0437\u044c\u043c\u0435\u0442 \u0438\u0437 \u043a\u044d\u0448\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435 \u0441\u043b\u043e\u0438 \u0447\u0442\u043e \u0431\u044b\u043b\u0438 \u0434\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 requirements, \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u043d\u043e\u0432\u044b\u0435.<\/p>\n<p>-d \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u043d\u0435 \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u043b\u043e\u0433\u0430\u043c\u0438 \u043a\u0430\u043a \u0440\u0430\u043d\u044c\u0448\u0435, \u0430 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442 \u0432\u0441\u0451 \u0432 \u0444\u043e\u043d\u0435. \u0422\u0430\u043a \u043a\u0430\u043a \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0441\u044f rmq \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043b\u043e\u0433\u043e\u0432 \u0440\u0435\u0437\u043a\u043e \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0451\u0442, \u0438 \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u043d\u0438\u043c\u0438 \u0443\u0436\u0435 \u043d\u0435 \u0442\u0430\u043a \u043f\u0440\u043e\u0441\u0442\u043e.<\/p>\n<p>\u041e\u0436\u0438\u0434\u0430\u0435\u043c \u043f\u043e\u043a\u0430 \u0432\u0441\u0435 \u0442\u0440\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0437\u0430\u043f\u0443\u0441\u0442\u044f\u0442\u0441\u044f<\/p>\n<p><code>Creating rmq ... done<\/code><\/p>\n<p><code>Creating djangoapp ... done<\/code><\/p>\n<p><code>Creating reactapp\u00a0 ... done<\/code><\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u0437\u0433\u043b\u044f\u043d\u0435\u043c \u0447\u0442\u043e \u043d\u0430\u043c \u0441\u043a\u0430\u0437\u0430\u043b\u0430 django \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435:<\/p>\n<p><code>docker-compose logs | grep djangoapp<\/code><\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/418\/78e\/162\/41878e16257d07b7f18bf5cc344119bc.png\" width=\"873\" height=\"563\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/418\/78e\/162\/41878e16257d07b7f18bf5cc344119bc.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043f\u043e\u043c\u0438\u043c\u043e \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043e\u0431\u0430 \u0432\u043e\u0440\u043a\u0435\u0440\u0430 \u043e\u0442\u0440\u0430\u043f\u043e\u0440\u0442\u043e\u0432\u0430\u043b\u0438 \u043d\u0430\u043c \u0447\u0442\u043e \u043e\u043d\u0438 \u0433\u043e\u0442\u043e\u0432\u044b \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043b\u0438\u0441\u044c \u043e\u043d\u0438 \u043d\u0435 \u0441\u0440\u0430\u0437\u0443, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043d\u043e \u0432 \u0446\u0435\u043b\u043e\u043c \u0432\u0441\u0451 \u043f\u0440\u043e\u0448\u043b\u043e \u0443\u0441\u043f\u0435\u0448\u043d\u043e.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a\u043e\u0433\u043e \u043d\u0438 \u0431\u0443\u0434\u044c \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0435\u043c\u0443 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1bb\/f1d\/9de\/1bbf1d9deaf4c154c2bf4ecbb3ac3a0f.png\" width=\"1228\" height=\"251\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1bb\/f1d\/9de\/1bbf1d9deaf4c154c2bf4ecbb3ac3a0f.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e! \u041c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u0430 \u0438 \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u043f\u0430\u0440\u043e\u0447\u043a\u0443. \u0421\u0445\u0435\u043c\u0430 \u0441 \u043a\u0440\u043e\u043b\u0438\u043a\u043e\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<p>\u0418\u0437 \u0432\u0441\u0435\u0439 \u0441\u0445\u0435\u043c\u044b \u043d\u0430\u043c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043b\u0438\u0448\u044c \u043f\u0435\u0440\u0435\u0435\u0445\u0430\u0442\u044c \u0441 SQLite \u043d\u0430 postgress, \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c nginx \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0448 \u0431\u044d\u043a\u0435\u043d\u0434 \u043d\u0435 \u0441\u043c\u043e\u0442\u0440\u0435\u043b \u043d\u0430\u0440\u0443\u0436\u0443, \u0430 \u0431\u044b\u043b \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0435\u0433\u043e \u0441\u0435\u0442\u0438.<\/p>\n<p>\u00a0\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0411\u0414.<\/p>\n<p>\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u0432\u0441\u0435 \u043d\u0430\u0448\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 docker-compose down, \u043e\u0442\u043a\u0440\u043e\u0435\u043c yml \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0441\u0435\u0440\u0432\u0438\u0441.<\/p>\n<pre><code class=\"yaml\">  postgres:     # \u0422\u0430\u043a \u0436\u0435 \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0441 \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430     image: postgres:15-alpine     container_name: postgresdb     # \u0427\u0442\u043e\u0431\u044b \u043d\u0430\u0448\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0435 \u043f\u0440\u043e\u043f\u0430\u0434\u0430\u043b\u0438 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c volume     volumes:       - postgres_volume:\/var\/lib\/postgresql\/data\/     # \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f. \u0438\u0445 \u043d\u0430\u0434\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0432 django.     environment:       - POSTGRES_USER=admin       - POSTGRES_PASSWORD=strong_password       - POSTGRES_DB=django_db     # \u0421\u0435\u0442\u044c     networks:       - myNetwork<\/code><\/pre>\n<p>Volume \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0434\u0435 \u043d\u0430\u0434\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c<\/p>\n<pre><code class=\"yaml\">volumes:   postgres_volume:   django_static_volume:   django_media_volume:   rabbitmq_data_volume:<\/code><\/pre>\n<p>\u0413\u043e\u0442\u043e\u0432\u043e. \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0434\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c django.<\/p>\n<p>\u041c\u044b \u0443\u043a\u0430\u0437\u0430\u043b\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0411\u0414 \u043b\u043e\u0433\u0438\u043d \u0438 \u043f\u0430\u0440\u043e\u043b\u044c. \u041c\u043e\u0436\u043d\u043e \u0438\u0445 \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0432 \u044f\u0432\u043d\u043e\u043c \u0432\u0438\u0434\u0435 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445, \u0430 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0439 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0432 \u0444\u0430\u0439\u043b\u0435 \u043f\u0440\u0438 \u0441\u0431\u043e\u0440\u043a\u0435.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432 <code>ProjectStudent<\/code> \u0444\u0430\u0439\u043b <code>.env<\/code><\/p>\n<p>\u0421\u0440\u0430\u0437\u0443 \u0432 \u043d\u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0442\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b \u0431\u044b \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u0438 \u0441\u0432\u0435\u0442\u0438\u0442\u044c \u0432 \u043a\u043e\u0434\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, SECRET_KEY<\/p>\n<p>\u0417\u0430\u043a\u0438\u043d\u0435\u043c \u0432 \u043d\u0435\u0433\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445. \u0412 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0411\u0414<\/p>\n<pre><code class=\"haskell\">SECRET_KEY=django-insecure-cfr4pr9x3dbm9vnmvclxn&amp;^a^ml-cl*=c#scbsxn_+m*5mt%z1 DEBUG=1 ALLOWED_HOSTS=*  POSTGRES_ENGINE=django.db.backends.postgresql POSTGRES_DB=django_db POSTGRES_USER=admin POSTGRES_PASSWORD=strong_password POSTGRES_HOST=postgres POSTGRES_PORT=5432 DATABASE=postgres<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c <code>settings.py<\/code><\/p>\n<p>\u0412\u043d\u043e\u0441\u0438\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"python\">SECRET_KEY = environ.get('SECRET_KEY') DEBUG = int(environ.get('DEBUG', default=0)) ALLOWED_HOSTS = environ.get('ALLOWED_HOSTS').split(' ')  ...  DATABASES = {     'default': {         'ENGINE': environ.get('POSTGRES_ENGINE', 'django.db.backends.sqlite3'),         'NAME': environ.get('POSTGRES_DB', BASE_DIR \/ 'db.sqlite3'),         'USER': environ.get('POSTGRES_USER', 'user'),         'PASSWORD': environ.get('POSTGRES_PASSWORD', 'password'),         'HOST': environ.get('POSTGRES_HOST', 'localhost'),         'PORT': environ.get('POSTGRES_PORT', '5432'),     } }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0435\u0440\u043d\u0451\u043c\u0441\u044f \u0432 yml \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0430\u0448 \u0444\u0430\u0439\u043b \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u043e\u0442 postgress \u0441\u0435\u0440\u0432\u0438\u0441\u0443 django.<\/p>\n<pre><code class=\"yaml\">    depends_on:       - postgres       - rmq     env_file:       - .\/.env<\/code><\/pre>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e! \u041d\u043e \u0435\u0441\u0442\u044c \u043e\u0434\u043d\u043e \u041d\u041e. \u0423 \u043d\u0430\u0441 \u0432 \u0434\u043e\u043a\u0435\u0440 \u0444\u0430\u0439\u043b\u0435 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0447\u0442\u043e \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u043d\u0430\u0434\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044e. \u041d\u043e \u043d\u044e\u0430\u043d\u0441 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u043c\u0438\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u0432 SQLite \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043b\u0435\u0436\u0430\u043b\u0430 \u0440\u044f\u0434\u043e\u043c, \u0430 \u043d\u0430 postgress, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0445\u043e\u0442\u044c \u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u0430 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u0445 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e, \u043a\u043e\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0433\u043e\u0442\u043e\u0432\u0430 \u043a \u0440\u0430\u0431\u043e\u0442\u0435.<\/p>\n<p>\u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0438 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u043f\u0440\u0430\u0432\u0438\u0442\u044c. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0440\u044f\u0434\u043e\u043c \u0441 dockerfile \u0441\u043a\u0440\u0438\u043f\u0442 entrypoint.sh \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0443 \u0447\u0442\u043e \u0435\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435.<\/p>\n<p><code>entrypoint.sh<\/code><\/p>\n<pre><code class=\"bash\">#!\/bin\/sh if [ \"$DATABASE\" = \"postgres\" ] then     # \u0435\u0441\u043b\u0438 \u0431\u0430\u0437\u0430 \u0435\u0449\u0435 \u043d\u0435 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430     echo \"\u0420\u0430\u043d\u043e...\"     # \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u0445\u043e\u0441\u0442\u0430 \u0438 \u043f\u043e\u0440\u0442\u0430     while ! nc -z $POSTGRES_HOST $POSTGRES_PORT; do       sleep 0.1     done     echo \"\u041f\u043e\u0440\u0430!\" fi # \u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438 python manage.py migrate exec \"$@\"<\/code><\/pre>\n<p>\u0442\u0430\u043a \u0436\u0435 \u0443\u0436\u0435 \u0432 \u0445\u043e\u0441\u0442\u043e\u0432\u043e\u0439 \u041e\u0421, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0441\u043a\u0440\u0438\u043f\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u043c. \u041f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0433\u0434\u0435 \u043e\u043d \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>chmod +x .\/ entrypoint.sh<\/code><\/p>\n<p>\u041f\u043b\u044e\u0441\u043e\u043c \u043a\u043e \u0432\u0441\u0435\u043c\u0443 \u0441 postgress \u043d\u0430\u0434\u043e \u043a\u0430\u043a \u0442\u043e \u043e\u0431\u0449\u0430\u0442\u044c\u0441\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043a\u0430\u043a \u0432 \u0441\u0430\u043c\u0443 \u041e\u0421 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430, \u0442\u0430\u043a \u0438 \u0432 pip.<\/p>\n<p>\u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c dockerfile  \u0434\u0436\u0430\u043d\u0433\u0438 \u0438 \u0434\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c pip<\/p>\n<pre><code class=\"yaml\">RUN apk update \\     &amp;&amp; apk add postgresql-dev gcc python3-dev musl-dev      # \u043e\u0431\u043d\u043e\u0432\u0438\u043c pip RUN pip install --upgrade pip<\/code><\/pre>\n<p>\u0418 \u0432 \u0441\u0430\u043c\u043e\u043c \u043a\u043e\u043d\u0446\u0435 \u0433\u0434\u0435 \u0431\u044b\u043b\u0430 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043c<\/p>\n<pre><code class=\"yaml\"># \u0421\u0434\u0435\u043b\u0430\u0435\u043c \u043f\u0435\u0440\u0432\u0443\u044e \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044e. ENTRYPOINT [\"\/usr\/src\/app\/entrypoint.sh\" ]<\/code><\/pre>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0442\u0435\u043f\u0435\u0440\u044c \u0442\u043e\u043f\u0430\u0435\u043c \u0441\u043d\u043e\u0432\u0430 \u043a django \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c <code>pip install psycopg2-binary<\/code><\/p>\n<p>\u0418 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 <code>pip freeze > app\/requirements.txt<\/code><\/p>\n<p>\u0421\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0438 \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0435\u0440\u0451\u043c: <code>docker-compose up -d \u2013build<\/code><\/p>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043b\u043e\u0433 django <code>docker-compose logs | grep djangoapp<\/code><\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/65c\/8e7\/87f\/65c8e787fc77c429dd58ef457135ddd8.png\" width=\"980\" height=\"848\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/65c\/8e7\/87f\/65c8e787fc77c429dd58ef457135ddd8.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0412\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0437\u0430\u043f\u0443\u0449\u0435\u043d, \u043d\u0430\u0448 \u0441\u043a\u0440\u0438\u043f\u0442 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043b, \u043d\u0430\u0448\u0438 \u0432\u043e\u0440\u043a\u0435\u0440\u044b \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u0440\u0438\u0446\u0435\u043f\u0438\u043b\u0438\u0441\u044c. \u041c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u0440\u0435\u0430\u043a\u0442 \u0438 \u0443\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u0438\u0442\u044c\u0441\u044f \u0447\u0442\u043e \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0414\u0430, \u043f\u0440\u043e\u0448\u043b\u044b\u0435 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0433\u0438\u043d\u0443\u043b\u0438, \u043d\u043e \u0432\u0437\u0430\u043c\u0435\u043d \u0443 \u043d\u0430\u0441 \u043d\u043e\u0432\u044b\u0435 \u0441\u0432\u0435\u0436\u0438\u0435 \u0438 \u043a\u0440\u0443\u0442\u044f\u0442\u0441\u044f \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0411\u0414. \u0422\u0430\u043a \u043a\u0430\u043a \u0443 \u043d\u0430\u0441 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d volume \u043a \u0441\u0435\u0440\u0432\u0438\u0441\u0443 postgress \u043d\u0430\u0448\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0438\u043a\u0443\u0434\u0430 \u043d\u0435 \u0434\u0435\u043d\u0443\u0442\u0441\u044f \u0438 \u0431\u0443\u0434\u0443\u0442 \u043e\u0441\u0442\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435. \u041c\u0438\u0433\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043d\u0438 \u043d\u0430 \u0447\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u0435 \u043f\u043e\u0432\u043b\u0438\u044f\u0435\u0442, \u0442.\u043a. \u0432\u0441\u0451 \u0443\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430 \u043c\u0435\u0441\u0442\u0435. \u041d\u0443 \u0430 \u0435\u0441\u043b\u0438 \u0432\u044b \u0443\u0434\u0430\u043b\u0438\u0442\u0435 \u0411\u0414 \u0438\u043b\u0438 volume \u0438 \u0440\u0435\u0448\u0438\u0442\u0435 \u043d\u0430\u0447\u0430\u0442\u044c \u0441 \u0447\u0438\u0441\u0442\u043e\u0433\u043e \u043b\u0438\u0441\u0442\u0430, \u0442\u043e \u0441\u043a\u0440\u0438\u043f\u0442 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u0441\u043d\u043e\u0432\u0430 \u0432\u043d\u0435\u0441\u0451\u0442 \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0439 \u043d\u0430\u0431\u043e\u0440.<\/p>\n<p>\u041d\u0443 \u0447\u0442\u043e, \u043e\u0441\u0442\u0430\u043b\u0430\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e nginx. \u0412 \u044d\u0442\u043e\u0439 \u0442\u0435\u043c\u0435 \u044f, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043f\u043e\u043a\u0430 \u043f\u043b\u0430\u0432\u0430\u044e, \u043d\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c.<\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432 \u043a\u043e\u0440\u043d\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0442\u0440\u0435\u0442\u0438\u0439 \u043a\u0430\u0442\u0430\u043b\u043e\u0433, \u0441 \u0438\u043c\u0435\u043d\u0435\u043c <code>nginx<\/code><\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c <code>dockerfile<\/code><\/p>\n<pre><code class=\"yaml\"># \u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u0438\u0437 \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0437\u0430 nginx:1.23-alpine FROM nginx:1.23-alpine # \u0423\u0434\u0430\u043b\u044f\u0435\u043c \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0439 \u043a\u043e\u043d\u0444\u0438\u0433 RUN rm \/etc\/nginx\/conf.d\/default.conf # \u041f\u043e\u0434\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0448 COPY .\/nginx.conf \/etc\/nginx\/conf.d\/<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0448 \u043a\u043e\u043d\u0444\u0438\u0433<\/p>\n<p><code>nginx.conf<\/code><\/p>\n<pre><code class=\"nginx\">upstream django_app {     # \u0421\u043f\u0438\u0441\u043e\u043a \u0431\u044d\u043a\u044d\u043d\u0434 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f     server django:8000; } server {     listen 80;     # \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f     location \/ {         # \u0415\u0441\u043b\u0438 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043a\u0440\u044b\u0442\u0430 \u043a\u043e\u0440\u043d\u0435\u0432\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430         # \u0432\u0441\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043f\u043e\u0439\u0434\u0443\u0442 \u043a \u043e\u0434\u043d\u043e\u043c\u0443 \u0438\u0437 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432         # \u0432 upstream django_proj         proxy_pass http:\/\/django_app;         # \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;         proxy_set_header Host $host;         # \u041e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435         proxy_redirect off;     }     # \u0421\u0442\u0430\u0442\u0438\u043a\u0430 \u0438 \u043c\u0435\u0434\u0438\u0430     location \/static\/ {         alias \/home\/src\/app\/static\/;     }     location \/media\/ {         alias \/home\/src\/app\/media\/;    } }<\/code><\/pre>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u0435\u043d\u044c\u043a\u043e. \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0441\u0435\u0440\u0432\u0438\u0441 \u0432 yml<\/p>\n<pre><code class=\"yaml\">nginx:     build: .\/nginx     container_name: nginx     networks:       - myNetwork     ports:       - 1337:80     depends_on:       - django     volumes:       - django_static_volume:\/home\/src\/app\/static       - django_media_volume:\/home\/src\/app\/media <\/code><\/pre>\n<p>\u0410 \u0442\u0430\u043a \u0436\u0435 \u043f\u043e\u0434\u043f\u0440\u0430\u0432\u0438\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441 django \u043f\u043e\u043c\u0435\u043d\u044f\u0435\u043c <code>ports: -8000:8000<\/code> \u043d\u0430<\/p>\n<pre><code class=\"yaml\">    expose:       - 8000<\/code><\/pre>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>docker-compose up -d \u2013build<\/code><\/p>\n<p>\u0418 \u0436\u0434\u0435\u043c \u043f\u043e\u043a\u0430 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0441\u044f \u0440\u0435\u0430\u043a\u0442 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/516\/f97\/645\/516f9764587180814196c9a84eb2d833.png\" width=\"988\" height=\"274\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/516\/f97\/645\/516f9764587180814196c9a84eb2d833.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0412\u0441\u0451 \u043d\u043e\u0440\u043c, \u043d\u043e \u0433\u0434\u0435 \u0434\u0430\u043d\u043d\u044b\u0435? \u0412\u0441\u0451 \u0434\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 react \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u0441\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043e\u0442\u0441\u044b\u043b\u0430\u0435\u0442 \u043d\u0430 \u0430\u0434\u0440\u0435\u0441 \u0431\u044d\u043a\u044d\u043d\u0434\u0430 \u043e\u0442 \u0438\u043c\u0435\u043d\u0438 \u0432\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430 \u0438 \u0432\u0430\u0448\u0435\u0433\u043e \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430. \u0418 \u0440\u0430\u043d\u044c\u0448\u0435 \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0431\u044d\u043a\u044d\u043d\u0434 \u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043b \u0441\u0432\u043e\u0439 \u043f\u043e\u0440\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u043d\u0430\u0440\u0443\u0436\u0443 \u0438 \u0445\u043e\u0441\u0442 \u043f\u0440\u043e\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u043b \u0441\u0432\u043e\u0439 8000 \u043f\u043e\u0440\u0442 \u043d\u0430 \u043f\u043e\u0440\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430. \u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u044d\u0442\u043e \u0443\u0431\u0440\u0430\u043b\u0438 \u0438 \u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 expose: -8000 \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0437\u0432\u0435\u0449\u0430\u0435\u0442 \u043e\u043a\u0440\u0443\u0436\u0430\u044e\u0449\u0438\u0445 \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f 8000 \u043f\u043e\u0440\u0442, \u043d\u043e \u0438\u0437\u0432\u043d\u0435 \u043d\u0430 \u043d\u0435\u0433\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043f\u043e\u043f\u0430\u0441\u0442\u044c. \u041d\u043e \u044d\u0442\u0438\u043c \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0432\u043e\u043a\u0440\u0443\u0433, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 nginx.<\/p>\n<p>\u0421\u043c\u0435\u043d\u0438\u043c \u0430\u0434\u0440\u0435\u0441 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0438 API \u043d\u0430 \u0440\u0435\u0430\u043a\u0442\u0435, \u0437\u0430\u0445\u043e\u0434\u0438\u043c \u0432 <code>index.js<\/code> \u0438 \u043f\u0440\u0430\u0432\u0438\u043c <\/p>\n<pre><code class=\"javascript\">export const API_URL = \"http:\/\/192.168.56.101:1337\/api\/students\/\" export const API_STATIC_MEDIA = \"http:\/\/192.168.56.101:1337\/\"<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/038\/863\/73e\/03886373e71c8ba7c5085af4fdc968c9.png\" width=\"1009\" height=\"555\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/038\/863\/73e\/03886373e71c8ba7c5085af4fdc968c9.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442! \u041a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b\u2026<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/bf3\/4ea\/38e\/bf34ea38eb40c78c95f43497fec5066d.jpg\" width=\"762\" height=\"429\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bf3\/4ea\/38e\/bf34ea38eb40c78c95f43497fec5066d.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041a\u043e\u0435-\u0447\u0442\u043e \u044f \u0432\u0441\u0451-\u0442\u0430\u043a\u0438 \u0437\u0430\u0431\u044b\u043b.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0437\u0430\u0439\u0434\u0435\u043c \u0432 \u0430\u0434\u043c\u0438\u043d\u043a\u0443 django<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f4f\/61a\/213\/f4f61a21301335e9a44f8b594981bf8a.png\" width=\"559\" height=\"175\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f4f\/61a\/213\/f4f61a21301335e9a44f8b594981bf8a.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041d\u0435 \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 \u043d\u0435\u0451, \u043f\u0440\u0430\u0432\u0434\u0430?<\/p>\n<p>\u0414\u0430, \u044f \u0437\u0430\u0431\u044b\u043b \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u043a\u0443. <\/p>\n<p>\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u0432\u0441\u0451 <code>docker-compose down<\/code>,<\/p>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u0432 <code>django_project<\/code>, \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <\/p>\n<p><code>python manage.py collectstatic<\/code><\/p>\n<p>\u0421\u0442\u0430\u0442\u0438\u043a\u0438 \u0442\u0430\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0438 \u043e\u043d\u0430, \u043a\u0430\u043a \u043d\u0438 \u0441\u0442\u0440\u0430\u043d\u043d\u043e, \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u0430 \u0438 \u0440\u0435\u0434\u043a\u043e \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f. \u0412\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0443\u0436\u0435 \u0432\u043d\u0435\u0441\u0435\u043d\u044b.<\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043e\u0431\u0440\u0430\u0442\u043d\u043e <\/p>\n<p><code>docker-compose up -d \u2013build<\/code><\/p>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0430\u0434\u043c\u0438\u043d\u043a\u0443.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a2d\/041\/596\/a2d0415969eec9b33d220894f9e4be08.png\" width=\"344\" height=\"257\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a2d\/041\/596\/a2d0415969eec9b33d220894f9e4be08.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0414\u0430, \u0432\u0441\u0451 \u041e\u041a.<\/p>\n<p>\u041d\u0443 \u0432\u043e\u0442 \u0432 \u0446\u0435\u043b\u043e\u043c \u0438 \u0432\u0441\u0451. \u041d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 Hello World \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u0438 \u0432 \u0446\u0435\u043b\u043e\u043c \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0438 \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0442\u044c.<\/p>\n<p>\u0414\u0430, \u0442\u0443\u0442 \u043c\u043d\u043e\u0433\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043f\u0440\u0430\u0432\u0438\u0442\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u0438 \u0432\u043d\u0435\u0437\u0430\u043f\u043d\u043e\u043c \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0435 rmq \u0432\u043e\u0440\u043a\u0435\u0440\u044b \u043e\u0442\u0432\u0430\u043b\u044f\u0442\u0441\u044f \u0438 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0432\u0435\u0441\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440. \u041d\u0430\u0434\u043e \u0434\u0430\u043b\u044c\u0448\u0435 \u043f\u043e \u0438\u0437\u0443\u0447\u0430\u0442\u044c nginx. \u0414\u0430 \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043c\u043d\u043e\u0433\u043e \u0447\u0435\u0433\u043e.<\/p>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\n<p><a href=\"https:\/\/github.com\/eldalex\/ProjectStudent\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/eldalex\/ProjectStudent<\/a><\/p>\n<p>\u0422\u0440\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u043d\u044f\u0442\u044c:<\/p>\n<p>1) <code>git clone https:\/\/github.com\/eldalex\/ProjectStudent<\/code><\/p>\n<p>\u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 <code>ProjectStudent<\/code><\/p>\n<p>2) <code>chmod +x django\/django_project\/entrypoint.sh<\/code><\/p>\n<p>3) <code>docker-compose up -d<\/code><\/p>\n<p>\u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u0438\u0432\u043d\u0430\u044f \u043a\u0440\u0438\u0442\u0438\u043a\u0430 \u043f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442\u0441\u044f) <\/p>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0447\u0442\u043e \u0434\u043e\u0447\u0438\u0442\u0430\u043b\u0438 \u0434\u043e \u043a\u043e\u043d\u0446\u0430!<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p> <!----> <!----><\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/713490\/\"> https:\/\/habr.com\/ru\/post\/713490\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h4>\u041d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 react \u0441 \u0431\u044d\u043a\u0435\u043d\u0434\u043e\u043c \u043d\u0430 Django, \u0441 \u0411\u0414 \u043d\u0430 postgres, \u0437\u0430\u0439\u0446\u0435\u043c, nginx \u0438 \u0432\u0441\u0451 \u0437\u0430\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0432 docker.<\/h4>\n<p>\u0414\u043b\u044f \u043a\u043e\u0433\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f?  \u041f\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u043c\u0443 \u0441\u0447\u0435\u0442\u0443 \u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0433\u043e \u0441\u0435\u0431\u044f, \u0447\u0442\u043e\u0431\u044b \u0445\u043e\u0442\u044c \u043a\u0430\u043a-\u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u043d\u0438\u044f \u0432 \u0441\u0432\u043e\u0435\u0439 \u0447\u0435\u0440\u0435\u043f\u0443\u0448\u043a\u0435. \u0410 \u0442\u0430\u043a\u0436\u0435 \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u0430 \u0442\u0430\u043a\u0438\u043c \u0436\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438, \u043a\u0430\u043a \u0438 \u044f \u0441\u0430\u043c. \u0412\u0441\u0451 \u0447\u0442\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u043d\u0438\u0436\u0435, \u043d\u0435 \u043f\u0440\u0435\u0442\u0435\u043d\u0434\u0443\u0435\u0442 \u043d\u0430 \u0438\u0441\u0442\u0438\u043d\u0443 \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u0438\u043d\u0441\u0442\u0430\u043d\u0446\u0438\u0438. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u043c\u0435\u0441\u0442\u0430\u043c\u0438 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0442\u0430\u043a, \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u044e\u0442. \u041d\u043e \u0442\u0430\u043a \u043a\u0430\u043a \u0443 \u043c\u0435\u043d\u044f \u043d\u0435 \u0441\u0442\u043e\u044f\u043b\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c enterprise \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0430 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0449\u0443\u043f\u0430\u0442\u044c \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a \u044d\u0442\u043e \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0442\u043e \u0432 \u0446\u0435\u043b\u043e\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u0435\u043d\u044f \u0443\u0441\u0442\u0440\u043e\u0438\u043b.<\/p>\n<p>\u0414\u043e\u043b\u0436\u0435\u043d \u0441\u0440\u0430\u0437\u0443 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0434\u0438\u0442\u044c, \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435 100% \u043b\u0438\u0447\u043d\u0430\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430. \u042d\u0442\u043e \u043f\u0440\u043e\u0435\u043a\u0442 \u0424\u0440\u0430\u043d\u043a\u0435\u043d\u0448\u0442\u0435\u0439\u043d \u0438\u0437 \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0442\u0430\u0442\u0435\u0439 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0430. \u041e\u0434\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435\u0439 \u044f \u043d\u0435 \u0441\u043c\u043e\u0433 \u043d\u0430\u0439\u0442\u0438, \u0438 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0441\u043b\u0435 \u0441\u0431\u043e\u0440\u043a\u0438 \u043d\u0430\u0447\u0430\u043b \u043f\u0438\u0441\u0430\u0442\u044c \u044d\u0442\u0443, \u0447\u0442\u043e\u0431\u044b \u0442\u0435, \u043a\u043e\u043c\u0443 \u044d\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0438 \u043f\u043e\u0449\u0443\u043f\u0430\u0442\u044c.<\/p>\n<figure class=\"\"><figcaption>\u041d\u0430\u0447\u043d\u0451\u043c \u043f\u043e\u0436\u0430\u043b\u0443\u0439<\/figcaption><\/figure>\n<p>\u041d\u0430\u0447\u043d\u0443 \u044f \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430.<\/p>\n<p>\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 WEB \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 React. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u043e\u0432, \u0441 \u043f\u0430\u0447\u043a\u043e\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0445 \u043f\u043e\u043b\u0435\u0439, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a \u0438\u043c\u044f, \u043f\u043e\u0447\u0442\u0430 \u0442\u0435\u043b\u0435\u0444\u043e\u043d \u0438 \u043f\u0440\u043e\u0447\u0435\u0435. \u0422\u0430\u043a \u0436\u0435 \u043a \u044d\u0442\u043e\u043c\u0443 \u0432\u0441\u0435\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u0438\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435. \u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a \u0436\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442. \u041c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u0430, \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0438\u043b\u0438 \u0436\u0435 \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435.<\/p>\n<p>\u0425\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u043d\u0430\u0448\u0438 \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u044b \u0431\u0443\u0434\u0443\u0442 \u043a\u0430\u043a \u0432\u044b \u0443\u0436\u0435 \u043f\u043e\u043d\u044f\u043b\u0438 \u0432 \u0411\u0414 postgress, \u0430 \u0432\u043e\u0442 \u0431\u0435\u0440\u0435\u0436\u043d\u043e \u0438\u0445 \u0442\u0443\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0435\u043c\u0438 \u043b\u044e\u0431\u0438\u043c\u0430\u044f Django \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043c\u0438 Django rest framework.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0437\u0430\u0445\u043e\u0434\u0438\u0442 \u043d\u0430 \u0432\u0435\u0431 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443. React \u0442\u043e\u043f\u0430\u0435\u0442 \u043d\u0430 Django \u0447\u0435\u0440\u0435\u0437 nginx, \u0437\u0430\u0431\u0438\u0440\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0441\u0442\u0440\u043e\u0438\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438. \u041c\u044b \u0432\u043e\u043b\u044c\u043d\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e. \u0417\u0430\u043a\u043e\u043d\u043e\u043c\u0435\u0440\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441, \u0437\u0430\u0447\u0435\u043c \u0432 \u044d\u0442\u043e\u0439 \u0441\u0445\u0435\u043c\u0435 Rabbit \u0438 \u0434\u0432\u0430 worker\u2019\u0430? \u0412\u0441\u0451 \u0434\u0435\u043b\u043e \u0432 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438\/\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u043d\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432 \u0444\u043e\u0440\u043c\u0443, \u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u043d\u043e\u0432\u044f\u0442\u0441\u044f, \u043d\u0435 \u0437\u0430\u0442\u0440\u0430\u0433\u0438\u0432\u0430\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435. \u041d\u043e \u0435\u0441\u043b\u0438 \u0442\u0430\u043a\u0438 \u043c\u044b \u0440\u0435\u0448\u0438\u043c \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u0438\u0442\u044c, \u0442\u043e \u0432\u0441\u0442\u0443\u043f\u0430\u0435\u0442 \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u044f \u0431\u0443\u0440\u043d\u043e\u0439 \u0434\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438\u043c\u044f, \u0438 \u043f\u043e\u043b\u0435 photo \u043d\u0430\u0448\u0435\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0443\u0442\u044c \u043a \u043d\u0435\u043c\u0443. \u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043d\u0430 rabbit \u0438 \u0432\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u0442\u0443\u0434\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c. Worker \u0437\u0430\u0431\u0438\u0440\u0430\u0435\u0442 \u0435\u0433\u043e, \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u0438 \u0448\u043b\u0451\u0442 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 \u0434\u0440\u0443\u0433\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c. \u0412\u0442\u043e\u0440\u043e\u0439 worker \u0437\u0430\u0431\u0438\u0440\u0430\u0435\u0442 \u0435\u0433\u043e \u0438 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u043f\u043e \u0443\u0436\u0435 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u043c\u0443 \u0432\u044b\u0448\u0435 \u043f\u0443\u0442\u0438. \u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0443\u0439\u0442\u0438 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0432\u0440\u0435\u043c\u044f, \u043d\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f \u043b\u0438\u0431\u043e \u0441\u0440\u0430\u0437\u0443, \u043b\u0438\u0431\u043e \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.   <\/p>\n<p>\u0412\u043e\u0442 \u0432 \u0446\u0435\u043b\u043e\u043c \u0438 \u0432\u0441\u0451.\u00a0 \u0427\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u043d\u0430\u0442\u044c \u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a \u0434\u0435\u043b\u0443, \u044f \u0432\u0441\u0435 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0434\u0435\u043b\u044b\u0432\u0430\u043b \u043d\u0430 windows, \u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u043b \u0443\u0436\u0435 \u043d\u0430 centos. <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/p>\n<p>\u042f \u043d\u0430\u0437\u0432\u0430\u043b \u0435\u0433\u043e ProjectStudent.<\/p>\n<p>1) Django.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0434\u043b\u044f Django \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u043d\u0435\u0433\u043e.<\/p>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u0432 \u044d\u0442\u043e\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 PowerShell (\u0438\u043b\u0438 cmd, \u043a\u043e\u043c\u0443 \u043a\u0430\u043a \u0443\u0434\u043e\u0431\u043d\u0435\u0435. \u0412 bash \u043c\u043e\u0436\u0435\u0442 \u043d\u0435\u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u0442\u044c\u0441\u044f)<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0438 \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e<\/p>\n<pre><code class=\"bash\">python3 -m venv --copies .\/env .\\env\\Scripts\\activate<\/code><\/pre>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c Django, \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u0441\u0440\u0430\u0437\u0443 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/p>\n<pre><code class=\"bash\">pip install Django django-admin startproject django_project python manage.py startapp students<\/code><\/pre>\n<p>\u0418\u0437 \u0442\u043e\u0433\u043e \u0447\u0442\u043e \u043d\u0430\u043c \u0435\u0449\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0432 Django \u0441\u0440\u0430\u0437\u0443 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c djangorestframework \u0438 django-cors-headers<\/p>\n<pre><code class=\"bash\">pip install django djangorestframework django-cors-headers<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c.<\/p>\n<p>\u041e\u0442\u043a\u0440\u043e\u0435\u043c \u0444\u0430\u0439\u043b django\\django_project\\django_project\\settings.py<\/p>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u044b \u043d\u0430 \u0431\u0443\u0434\u0443\u0449\u0435\u0435, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, middleware<\/p>\n<pre><code class=\"python\">import os from pathlib import Path from os import environ  INSTALLED_APPS = [     ...     'rest_framework',     'corsheaders',     'students' ]  MIDDLEWARE = [     ...     'corsheaders.middleware.CorsMiddleware',     'django.middleware.common.CommonMiddleware', ]<\/code><\/pre>\n<p>CORS_ORIGIN_ALLOW_ALL\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u0434\u043e\u043b\u0436\u0435\u043d \u043b\u0438 Django \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u0442\u043a\u0440\u044b\u0442 \u0438\u043b\u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0437\u0430\u043a\u0440\u044b\u0442 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u043d\u0430\u043c \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u044d\u0442\u043e \u043d\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0435\u0433\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c.<\/p>\n<pre><code class=\"python\">CORS_ORIGIN_ALLOW_ALL = True<\/code><\/pre>\n<p>\u0418 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u0438\u043a\u0438<\/p>\n<pre><code class=\"python\">STATIC_URL = '\/static\/' STATIC_ROOT = os.path.join(BASE_DIR, 'static')  MEDIA_URL = '\/media\/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')<\/code><\/pre>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e. \u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u0439\u043c\u0435\u043c\u0441\u044f \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u0430\u043c\u0438.<\/p>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043c\u043e\u0434\u0435\u043b\u044c django\\django_project\\students\\models.py <\/p>\n<p>\u0438 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043c\u043e\u0434\u0435\u043b\u044c<\/p>\n<pre><code class=\"python\">from django.db import models  class Student(models.Model):     name = models.CharField(\"Name\", max_length=240)     email = models.EmailField()     document = models.CharField(\"Document\", max_length=20)     phone = models.CharField(max_length=20)     registrationDate = models.DateField(\"Registration Date\", auto_now_add=True)     photo = models.CharField(\"URL\", max_length=512)      def __str__(self):         return self.name<\/code><\/pre>\n<p>\u0413\u043e\u0442\u043e\u0432\u043e. \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0432\u0441\u0451 \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b\u044b \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438 \u0438 \u043c\u0438\u0433\u0440\u0438\u0440\u0443\u0435\u043c.<\/p>\n<pre><code class=\"bash\">Python manage.py makemigrations python manage.py migrate<\/code><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0441\u0438\u043b\u044c\u043d\u043e \u0437\u0430\u043c\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438 \u0444\u0438\u043a\u0441\u0442\u0443\u0440\u0430\u043c\u0438, \u0441\u0440\u0430\u0437\u0443 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0444\u0430\u0439\u043b \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u0443\u0434\u0430.<\/p>\n<pre><code class=\"bash\">python manage.py makemigrations --empty --name students students<\/code><\/pre>\n<p>\u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043d\u0430\u0434\u043e \u043f\u043e\u0434\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0444\u0430\u0439\u043b django\\django_project\\students\\migrations\\0002_students.py<\/p>\n<p>\u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043c \u0435\u0433\u043e \u043a \u0442\u0430\u043a\u043e\u043c\u0443 \u0432\u0438\u0434\u0443:<\/p>\n<pre><code class=\"python\">from django.db import migrations  def create_data(apps, schema_editor):     Student = apps.get_model('students', 'Student')     Student(name=\"Joe Silver\", email=\"joe@email.com\", document=\"22342342\", phone=\"00000000\", photo='media\/photo\/nophoto.png').save()     Student(name=\"John Smith\", email=\"john@email.com\", document=\"11111111\", phone=\"11111111\", photo='media\/photo\/nophoto.png').save()     Student(name=\"Alex Smth\", email=\"alex@email.com\", document=\"22222222\", phone=\"22222222\", photo='media\/photo\/nophoto.png').save()     Student(name=\"Kira Night\", email=\"kira@email.com\", document=\"33333333\", phone=\"33333333\", photo='media\/photo\/nophoto.png').save()     Student(name=\"Amanda Lex\", email=\"amanda@email.com\", document=\"44444444\", phone=\"44444444\", photo='media\/photo\/nophoto.png').save()     Student(name=\"Oni Musha\", email=\"oni@email.com\", document=\"44444444\", phone=\"44444444\", photo='media\/photo\/nophoto.png').save()  class Migration(migrations.Migration):      dependencies = [         ('students', '0001_initial'),     ]      operations = [         migrations.RunPython(create_data),     ] <\/code><\/pre>\n<p>\u0418 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043c \u0435\u0449\u0451 \u043e\u0434\u043d\u0443 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044e<\/p>\n<pre><code class=\"bash\">python manage.py migrate<\/code><\/pre>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e! \u0422\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u043d\u0430\u0448\u0435\u043c\u0443 api<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043d\u0430\u0448\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445. \u0444\u0430\u0439\u043b django\\django_project\\students\\serializers.py<\/p>\n<pre><code class=\"python\">from rest_framework import serializers from .models import Student  class StudentSerializer(serializers.ModelSerializer):      class Meta:         model = Student          fields = ('pk', 'name', 'email', 'document', 'phone', 'registrationDate','photo') <\/code><\/pre>\n<p>\u0442\u0430\u043a, \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0432 uls.py, \u0430\u0434\u0440\u0435\u0441\u0430 \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043d\u0430\u0448\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c django\\django_project\\django_project\\urls.py <\/p>\n<p>\u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e re_path, \u043d\u0430\u0448\u0435 \u0441\u0442\u0443\u0434\u0435\u043d\u0447\u0435\u0441\u043a\u043e\u0435 view \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u0438\u043a\u0438.<\/p>\n<pre><code class=\"python\">from django.contrib import admin from django.urls import path, re_path from students import views from django.conf import settings from django.conf.urls.static import static  urlpatterns = [     path('admin\/', admin.site.urls),     re_path(r'^api\/students\/$', views.students_list),     re_path(r'^api\/students\/(\\d+)$', views.students_detail), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u043a view<\/p>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c django\\django_project\\students\\views.py<\/p>\n<pre><code class=\"python\">from rest_framework.response import Response from rest_framework.decorators import api_view from rest_framework import status from .serializers import *  # Create your views here.  @api_view(['GET', 'POST']) def students_list(request):     if request.method == 'GET':         data = Student.objects.all()         serializer = StudentSerializer(data, context={'request': request}, many=True)         return Response(serializer.data)     elif request.method == 'POST':         print('post')         serializer = StudentSerializer(data=request.data)         if serializer.is_valid():             serializer.save()             return Response(status=status.HTTP_201_CREATED)         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)  @api_view(['PUT', 'DELETE']) def students_detail(request, pk):     try:         student = Student.objects.get(pk=pk)     except Student.DoesNotExist:         return Response(status=status.HTTP_404_NOT_FOUND)     if request.method == 'PUT':         serializer = StudentSerializer(student, data=request.data, context={'request': request})         if serializer.is_valid():             serializer.save()             return Response(status=status.HTTP_204_NO_CONTENT)         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)     elif request.method == 'DELETE':         student.delete()         return Response(status=status.HTTP_204_NO_CONTENT)  <\/code><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0443\u0431\u0435\u0434\u0438\u043c\u0441\u044f, \u0447\u0442\u043e \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440<\/p>\n<pre><code class=\"bash\">python manage.py runserver<\/code><\/pre>\n<p>\u0438 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 <a href=\"http:\/\/127.0.0.1:8000\/api\/students\/\" rel=\"noopener noreferrer nofollow\">http:\/\/127.0.0.1:8000\/api\/students\/<\/a><\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0412\u0438\u0434\u0438\u043c \u043d\u0430\u0448\u0438\u0445 \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u043e\u0432. \u0417\u043d\u0430\u0447\u0438\u0442 \u0432\u0441\u0451 \u043e\u043a!<\/p>\n<p>\u0422\u0430\u043a \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u044b \u0441 django \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438, \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a react.<\/p>\n<p>\u0422\u0430\u043c \u043f\u0438\u0441\u0430\u043d\u0438\u043d\u044b \u043f\u043e\u0431\u043e\u043b\u044c\u0448\u0435 \u0431\u0443\u0434\u0435\u0442, \u043d\u043e \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043a\u043e\u0434. \u041f\u043e\u0435\u0445\u0430\u043b\u0438!<\/p>\n<p>\u041a\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435?<\/p>\n<p>App \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0434\u0432\u0443\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, Header \u0438 Home. \u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c Home \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 ListStudents \u0438 ModalStudent (\u043a\u043d\u043e\u043f\u043a\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u0430)<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0412\u044b\u0445\u043e\u0434\u0438\u043c \u0432 \u043a\u043e\u0440\u043d\u0435\u0432\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443<\/p>\n<pre><code class=\"bash\">npx create-react-app reactapp<\/code><\/pre>\n<p>\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u043f\u0430\u0440\u0443 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 <\/p>\n<pre><code class=\"bash\">npm i axios reactstrap bootstrap<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u043e\u0437\u0434\u0430\u043b\u043e\u0441\u044c, \u043d\u0430\u0447\u043d\u0435\u043c \u043d\u0430\u043a\u0438\u0434\u044b\u0432\u0430\u0442\u044c \u0432 \u043d\u0435\u0433\u043e \u0441\u0432\u043e\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432 src \u043a\u0430\u0442\u0430\u043b\u043e\u0433 components, \u0438 \u0432 \u043f\u043e\u0434\u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0438 app, appHeader, appHome, appListStudents, appModalStudent, appPhotoModal, appRemoveStudent,appStudentForm.<\/p>\n<p>\u041a\u0430\u043a \u0432\u044b \u043f\u043e\u043d\u044f\u043b\u0438, \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 \u0438 \u0444\u0430\u0439\u043b\u0435. <\/p>\n<p>\u0412 app \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0438\u043c, \u043f\u043e \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u043e js \u0444\u0430\u0439\u043b\u0443 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439.<\/p>\n<figure class=\"\"><figcaption>\u0412 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a.<\/figcaption><\/figure>\n<p>\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u043a \u043a\u043e\u0434\u0443 react \u044f \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e \u043d\u0435 \u0434\u0435\u043b\u0430\u043b, \u0442\u0430\u043c \u0432\u0441\u0451 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u0445. \u0422\u0430\u043c \u0433\u0434\u0435 \u044f \u044d\u0442\u043e \u043f\u043e\u0434\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u043b \u0432\u0441\u0451 \u0431\u044b\u043b\u043e \u0432 \u043a\u043b\u0430\u0441\u0441\u043e\u0432\u044b\u0445, \u043d\u043e<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-344644","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/344644","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=344644"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/344644\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=344644"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=344644"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=344644"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}