PR-16 Исправление формы заполнения готовых проектов

Изменение model WorkSell
Форма создания готовых проектов закончена
remotes/origin/PR-49
booblegum 9 years ago
parent 0b8c803dad
commit 96745cc2fa
  1. 6
      api/urls.py
  2. 10
      api/views.py
  3. BIN
      assets/img/aui-icon-close.png
  4. BIN
      assets/img/close-img-icon.png
  5. 97
      assets/js/build/create_project.js
  6. 212
      assets/js/build/create_worksell.js
  7. 1905
      assets/js/build/init_create_worksell.js
  8. 65
      assets/js/build/init_customer_project_create.js
  9. 7
      assets/js/src/create_worksell.js
  10. 2
      assets/js/src/customer_project_create.js
  11. 104
      assets/js/src/init_create_worksell.js
  12. 28
      assets/js/src/seeds/file_upload.js
  13. 47
      assets/js/src/seeds/image_upload.js
  14. 16
      assets/js/src/seeds/textareas_max-rows.js
  15. 36
      assets/js/src/utils.js
  16. 9
      assets/lib/proekton-components/sass/parts/_selected-container.sass
  17. 31
      assets/sass/components/custom-components.sass
  18. 14
      common/serializers.py
  19. 6
      projects/templates/customer_project_create.html
  20. 59
      templates/partials/sass/header.sass
  21. 46
      users/templates/contractor_profile.html
  22. 7
      webpack.config.js
  23. 3
      work_sell/admin.py
  24. 75
      work_sell/forms.py
  25. 30
      work_sell/migrations/0020_auto_20161207_0034.py
  26. 27
      work_sell/migrations/0021_auto_20161207_1210.py
  27. 37
      work_sell/migrations/0022_auto_20161207_1213.py
  28. 25
      work_sell/models.py
  29. 263
      work_sell/templates/worksell_create.html
  30. 7
      work_sell/urls.py
  31. 100
      work_sell/views.py

@ -5,6 +5,7 @@ from .views import (
ContractorResumeFilesViewSet, ContractorResumeFilesViewSet,
ContractorResumeViewSet, ContractorResumeViewSet,
DocumentViewSet, DocumentViewSet,
ElFormatViewSet,
LocationViewSet, LocationViewSet,
LocationViewSetFlat, LocationViewSetFlat,
MessageViewSet, MessageViewSet,
@ -29,9 +30,12 @@ from .views import (
router = routers.DefaultRouter() router = routers.DefaultRouter()
router.register(r'answers', AnswerViewSet) router.register(r'answers', AnswerViewSet)
router.register(r'building_classifications', BuildingClassificationViewSet)
router.register(r'construction_type', ConstructionTypeViewSet)
router.register(r'contractorresume', ContractorResumeViewSet) router.register(r'contractorresume', ContractorResumeViewSet)
router.register(r'contractorresumefiles', ContractorResumeFilesViewSet) router.register(r'contractorresumefiles', ContractorResumeFilesViewSet)
router.register(r'documents', DocumentViewSet) router.register(r'documents', DocumentViewSet)
router.register(r'el_format', ElFormatViewSet)
router.register(r'locations', LocationViewSet) router.register(r'locations', LocationViewSet)
router.register(r'locations_flat', LocationViewSetFlat) router.register(r'locations_flat', LocationViewSetFlat)
router.register(r'message', MessageViewSet, base_name='Message') router.register(r'message', MessageViewSet, base_name='Message')
@ -41,8 +45,6 @@ router.register(r'portfolio-photos', PortfolioPhotoViewSet)
router.register(r'portfolios', PortfolioViewSet) router.register(r'portfolios', PortfolioViewSet)
router.register(r'projects', ProjectViewSet) router.register(r'projects', ProjectViewSet)
router.register(r'realties', RealtyViewSet) router.register(r'realties', RealtyViewSet)
router.register(r'building_classifications', BuildingClassificationViewSet)
router.register(r'construction_type', ConstructionTypeViewSet)
router.register(r'reviews', ReviewViewSet) router.register(r'reviews', ReviewViewSet)
router.register(r'specializations', SpecializationViewSet) router.register(r'specializations', SpecializationViewSet)
router.register(r'specializations_flat', SpecializationViewSetFlat) router.register(r'specializations_flat', SpecializationViewSetFlat)

@ -11,7 +11,7 @@ from chat.models import Message, Notes, Documents, NewMessage
from chat.serializers import MessageSerializer, NoteSerializer, DocumentsSerializer from chat.serializers import MessageSerializer, NoteSerializer, DocumentsSerializer
from common.filters import LocationFilterSet from common.filters import LocationFilterSet
from common.models import Location from common.models import Location
from common.serializers import LocationSerializer, LocationSerializerFlat from common.serializers import LocationSerializer, LocationSerializerFlat, ElFormatSerializer
from projects.filters import ( from projects.filters import (
ProjectFilterSet, RealtyFilterSet, StageFilterSet, PortfolioFilterSet, OrderFilterSet, ProjectFilterSet, RealtyFilterSet, StageFilterSet, PortfolioFilterSet, OrderFilterSet,
PortfolioPhotoFilterSet, AnswerFilterSet, BuildingClassficationFilterSet, ConstructionTypeFilterSet PortfolioPhotoFilterSet, AnswerFilterSet, BuildingClassficationFilterSet, ConstructionTypeFilterSet
@ -33,7 +33,7 @@ from users.models import User, ContractorResumeFiles, ContractorResume, Team
from users.serializers import UserSerializer, ContractorResumeFilesSerializer, ContractorResumeSerializer, \ from users.serializers import UserSerializer, ContractorResumeFilesSerializer, ContractorResumeSerializer, \
TeamSerializer TeamSerializer
from work_sell.filters import WorkSellFilterSet, WorkSellPhotoFilterSet from work_sell.filters import WorkSellFilterSet, WorkSellPhotoFilterSet
from work_sell.models import WorkSell, WorkSellPhoto from work_sell.models import WorkSell, WorkSellPhoto, ElFormat
from work_sell.serializers import WorkSellSerializer, WorkSellPhotoSerializer from work_sell.serializers import WorkSellSerializer, WorkSellPhotoSerializer
@ -230,6 +230,12 @@ class LocationViewSetFlat(ModelViewSet):
filter_class = LocationFilterSet filter_class = LocationFilterSet
class ElFormatViewSet(ModelViewSet):
queryset = ElFormat.objects.all().order_by('name')
serializer_class = ElFormatSerializer
# filter_class = LocationFilterSet
class PortfolioPagination(PageNumberPagination): class PortfolioPagination(PageNumberPagination):
page_size = settings.API_PAGE_SIZE # Default page size page_size = settings.API_PAGE_SIZE # Default page size
page_size_query_param = 'page_size' # Provide custom page size through a query param page_size_query_param = 'page_size' # Provide custom page size through a query param

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

@ -48,19 +48,15 @@
var _file_upload = __webpack_require__(1); var _file_upload = __webpack_require__(1);
var _file_upload2 = _interopRequireDefault(_file_upload); var _extended_field = __webpack_require__(3);
var _extended_field = __webpack_require__(2); var _custom_check = __webpack_require__(4);
var _custom_check = __webpack_require__(3); var _read_more = __webpack_require__(5);
var _read_more = __webpack_require__(4); var _only_one_checkbox = __webpack_require__(6);
var _only_one_checkbox = __webpack_require__(5); var _test_seeds = __webpack_require__(7);
var _test_seeds = __webpack_require__(6);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function showHideRealry() { function showHideRealry() {
var check = $('#checkbox-sb-realty'); var check = $('#checkbox-sb-realty');
@ -75,7 +71,7 @@
} }
$(function () { $(function () {
(0, _file_upload2.default)(); (0, _file_upload.fileUploadInit)();
(0, _extended_field.extendedFieldInit)(); (0, _extended_field.extendedFieldInit)();
(0, _custom_check.customCheckInit)(); (0, _custom_check.customCheckInit)();
showHideRealry(); showHideRealry();
@ -85,30 +81,16 @@
/***/ }, /***/ },
/* 1 */ /* 1 */
/***/ function(module, exports) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
Object.defineProperty(exports, "__esModule", { Object.defineProperty(exports, "__esModule", {
value: true value: true
}); });
exports.default = fileUploadInit; exports.fileUploadInit = undefined;
function humanFileSize(bytes, si) {
var thresh = si ? 1000 : 1024;
if (Math.abs(bytes) < thresh) return bytes + ' B';
var units = si ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; var _utils = __webpack_require__(2);
var u = -1;
do {
bytes /= thresh;
++u;
} while (Math.abs(bytes) >= thresh && u < units.length - 1);
return bytes.toFixed(1) + ' ' + units[u];
}
function fileUploadInit() { function fileUploadInit() {
var $fileUploadContainer = $('#fileUploadContainer'); var $fileUploadContainer = $('#fileUploadContainer');
@ -123,7 +105,7 @@
var filePath = $fileInput.val().replace(/\\/g, '/'); var filePath = $fileInput.val().replace(/\\/g, '/');
var fileName = path.basename(filePath); var fileName = path.basename(filePath);
//var fileExt = path.extname(filePath) //var fileExt = path.extname(filePath)
var fileSize = $fileInput.get(0).files && humanFileSize($fileInput.get(0).files[0].size); var fileSize = $fileInput.get(0).files && (0, _utils.humanFileSize)($fileInput.get(0).files[0].size);
if (fileName) { if (fileName) {
$fileUploadWidget.find('.file-upload-label').text(fileName + ' ' + fileSize); $fileUploadWidget.find('.file-upload-label').text(fileName + ' ' + fileSize);
@ -141,19 +123,60 @@
var $btn = $(this); var $btn = $(this);
$btn.closest('.file-upload-widget').remove(); $btn.closest('.file-upload-widget').remove();
}); });
$fileUploadContainer.on('click', '.existing-file-remove-btn', function ($evt) {
var $btn = $(this);
$btn.closest('.existing-file-widget').remove();
});
} }
exports.fileUploadInit = fileUploadInit;
/***/ }, /***/ },
/* 2 */ /* 2 */
/***/ function(module, exports) { /***/ function(module, exports) {
'use strict'; 'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) == name + '=') {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function humanFileSize(bytes, si) {
var thresh = si ? 1000 : 1024;
if (Math.abs(bytes) < thresh) return bytes + ' B';
var units = si ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
var u = -1;
do {
bytes /= thresh;
++u;
} while (Math.abs(bytes) >= thresh && u < units.length - 1);
return bytes.toFixed(1) + ' ' + units[u];
}
exports.humanFileSize = humanFileSize;
exports.getCookie = getCookie;
/***/ },
/* 3 */
/***/ function(module, exports) {
'use strict';
Object.defineProperty(exports, "__esModule", { Object.defineProperty(exports, "__esModule", {
value: true value: true
}); });
@ -179,7 +202,7 @@
exports.extendedFieldInit = extendedFieldInit; exports.extendedFieldInit = extendedFieldInit;
/***/ }, /***/ },
/* 3 */ /* 4 */
/***/ function(module, exports) { /***/ function(module, exports) {
"use strict"; "use strict";
@ -208,7 +231,7 @@
exports.customCheckInit = customCheckInit; exports.customCheckInit = customCheckInit;
/***/ }, /***/ },
/* 4 */ /* 5 */
/***/ function(module, exports) { /***/ function(module, exports) {
"use strict"; "use strict";
@ -234,7 +257,7 @@
exports.readMoreInit = readMoreInit; exports.readMoreInit = readMoreInit;
/***/ }, /***/ },
/* 5 */ /* 6 */
/***/ function(module, exports) { /***/ function(module, exports) {
"use strict"; "use strict";
@ -265,7 +288,7 @@
exports.onlyOneCheckboxInit = onlyOneCheckboxInit; exports.onlyOneCheckboxInit = onlyOneCheckboxInit;
/***/ }, /***/ },
/* 6 */ /* 7 */
/***/ function(module, exports) { /***/ function(module, exports) {
"use strict"; "use strict";

@ -0,0 +1,212 @@
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var _file_upload = __webpack_require__(1);
var _image_upload = __webpack_require__(8);
$(function () {
// fileUploadInit();
(0, _image_upload.imageUploadInit)();
});
/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.fileUploadInit = undefined;
var _utils = __webpack_require__(2);
function fileUploadInit() {
var $fileUploadContainer = $('#fileUploadContainer');
$('#fileUploadAddBtn').on('click', function ($evt) {
$fileUploadContainer.find('.file-upload-widget').last().find('.file-upload-input').click();
});
$fileUploadContainer.on('change', '.file-upload-input', function ($evt) {
var $fileInput = $(this);
var $fileUploadWidget = $fileInput.closest('.file-upload-widget');
var filePath = $fileInput.val().replace(/\\/g, '/');
var fileName = path.basename(filePath);
//var fileExt = path.extname(filePath)
var fileSize = $fileInput.get(0).files && (0, _utils.humanFileSize)($fileInput.get(0).files[0].size);
if (fileName) {
$fileUploadWidget.find('.file-upload-label').text(fileName + ' ' + fileSize);
var $newFileUploadWidget = $fileUploadWidget.clone();
$newFileUploadWidget.find('.file-upload-label').text('');
$fileUploadContainer.find('ul').first().append($newFileUploadWidget);
$fileUploadWidget.css('display', 'block');
}
});
$fileUploadContainer.on('click', '.file-upload-remove-btn', function ($evt) {
var $btn = $(this);
$btn.closest('.file-upload-widget').remove();
});
}
exports.fileUploadInit = fileUploadInit;
/***/ },
/* 2 */
/***/ function(module, exports) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) == name + '=') {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function humanFileSize(bytes, si) {
var thresh = si ? 1000 : 1024;
if (Math.abs(bytes) < thresh) return bytes + ' B';
var units = si ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
var u = -1;
do {
bytes /= thresh;
++u;
} while (Math.abs(bytes) >= thresh && u < units.length - 1);
return bytes.toFixed(1) + ' ' + units[u];
}
exports.humanFileSize = humanFileSize;
exports.getCookie = getCookie;
/***/ },
/* 3 */,
/* 4 */,
/* 5 */,
/* 6 */,
/* 7 */,
/* 8 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.imageUploadInit = undefined;
var _utils = __webpack_require__(2);
function imageUploadInit() {
var $fileUploadContainer = $('#fileUploadContainer');
$('#fileUploadAddBtn').on('click', function ($evt) {
$fileUploadContainer.find('.file-upload-widget').last().find('.file-upload-input').click();
});
$fileUploadContainer.on('change', '.file-upload-input', function ($evt) {
var $fileInput = $(this);
var $fileUploadWidget = $fileInput.closest('.file-upload-widget');
var $fileImg = $fileUploadWidget.find('img');
var filePath = $fileInput.val().replace(/\\/g, '/');
var fileName = path.basename(filePath);
var fileSize = $fileInput.get(0).files && (0, _utils.humanFileSize)($fileInput.get(0).files[0].size);
if (fileName) {
$fileUploadWidget.find('.file-upload-label').text(fileName + ' ' + fileSize);
var $newFileUploadWidget = $fileUploadWidget.clone();
$newFileUploadWidget.find('.file-upload-label').text('');
$fileUploadContainer.find('.list-new-new').append($newFileUploadWidget);
$fileUploadWidget.css('display', 'block');
if ($fileImg) {
var reader = new FileReader();
reader.onload = function (e) {
$fileImg.attr('src', e.target.result);
};
reader.readAsDataURL($fileInput[0].files[0]);
}
}
});
$fileUploadContainer.on('click', '.file-upload-remove-img-btn', function ($evt) {
var $btn = $(this);
$btn.closest('.file-upload-widget').remove();
});
} //TODO: оформить Upload'еры в виде классов
exports.imageUploadInit = imageUploadInit;
/***/ }
/******/ ]);

File diff suppressed because it is too large Load Diff

@ -46,27 +46,27 @@
'use strict'; 'use strict';
var _SelectedContainer = __webpack_require__(7); var _SelectedContainer = __webpack_require__(10);
var _SelectedContainer2 = _interopRequireDefault(_SelectedContainer); var _SelectedContainer2 = _interopRequireDefault(_SelectedContainer);
var _SelectedContainerCreate = __webpack_require__(11); var _SelectedContainerCreate = __webpack_require__(14);
var _SelectedContainerCreate2 = _interopRequireDefault(_SelectedContainerCreate); var _SelectedContainerCreate2 = _interopRequireDefault(_SelectedContainerCreate);
var _NoTreeSelect = __webpack_require__(12); var _NoTreeSelect = __webpack_require__(15);
var _NoTreeSelect2 = _interopRequireDefault(_NoTreeSelect); var _NoTreeSelect2 = _interopRequireDefault(_NoTreeSelect);
var _TreeSelect = __webpack_require__(14); var _TreeSelect = __webpack_require__(17);
var _TreeSelect2 = _interopRequireDefault(_TreeSelect); var _TreeSelect2 = _interopRequireDefault(_TreeSelect);
var _SingleTreeSelect = __webpack_require__(15); var _SingleTreeSelect = __webpack_require__(18);
var _SingleTreeSelect2 = _interopRequireDefault(_SingleTreeSelect); var _SingleTreeSelect2 = _interopRequireDefault(_SingleTreeSelect);
var _SelectOrCreate = __webpack_require__(16); var _SelectOrCreate = __webpack_require__(19);
var _SelectOrCreate2 = _interopRequireDefault(_SelectOrCreate); var _SelectOrCreate2 = _interopRequireDefault(_SelectOrCreate);
@ -174,19 +174,15 @@
if (!sb_realty_top.dataTree.data.length) sb_realty_top.hide(); if (!sb_realty_top.dataTree.data.length) sb_realty_top.hide();
}); });
select_realty.on("add", function (args) { select_realty.on("add", function (args) {
// console.log("add args = ", args);
console.log('on add');
//TODO: Костыли!!! //TODO: Костыли!!!
$('#checkbox-sb-realty').prop("checked", true); $('#checkbox-sb-realty').prop("checked", true);
sb_realty.show(); sb_realty.show();
var id = args[0]; var id = args[0];
if (id.text) return; if (id.text) return;
console.log("id = ", id);
var el = sb_realty.dataTree.getElementById(id); var el = sb_realty.dataTree.getElementById(id);
sb_realty_top.$searchInput.val(el.name); sb_realty_top.$searchInput.val(el.name);
sb_realty_top.selectedEl.id = id; sb_realty_top.selectedEl.id = id;
sb_realty_top.selectedEl.value = el.name; sb_realty_top.selectedEl.value = el.name;
// sb_realty_top.show();
sb_realty.selectedEl.id = id; sb_realty.selectedEl.id = id;
sb_realty._fillBoxes(); sb_realty._fillBoxes();
}); });
@ -212,7 +208,10 @@
/* 4 */, /* 4 */,
/* 5 */, /* 5 */,
/* 6 */, /* 6 */,
/* 7 */ /* 7 */,
/* 8 */,
/* 9 */,
/* 10 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -227,15 +226,15 @@
var _desc, _value, _class; // ` var _desc, _value, _class; // `
var _DataTree = __webpack_require__(8); var _DataTree = __webpack_require__(11);
var _DataTree2 = _interopRequireDefault(_DataTree); var _DataTree2 = _interopRequireDefault(_DataTree);
var _NoTreeData = __webpack_require__(9); var _NoTreeData = __webpack_require__(12);
var _NoTreeData2 = _interopRequireDefault(_NoTreeData); var _NoTreeData2 = _interopRequireDefault(_NoTreeData);
var _decorators = __webpack_require__(10); var _decorators = __webpack_require__(13);
var _decorators2 = _interopRequireDefault(_decorators); var _decorators2 = _interopRequireDefault(_decorators);
@ -466,7 +465,7 @@
exports.default = SelectedContainer; exports.default = SelectedContainer;
/***/ }, /***/ },
/* 8 */ /* 11 */
/***/ function(module, exports) { /***/ function(module, exports) {
"use strict"; "use strict";
@ -621,7 +620,7 @@
exports.default = DataTree; exports.default = DataTree;
/***/ }, /***/ },
/* 9 */ /* 12 */
/***/ function(module, exports) { /***/ function(module, exports) {
"use strict"; "use strict";
@ -677,7 +676,7 @@
exports.default = NoTreeData; exports.default = NoTreeData;
/***/ }, /***/ },
/* 10 */ /* 13 */
/***/ function(module, exports) { /***/ function(module, exports) {
"use strict"; "use strict";
@ -761,7 +760,7 @@
// export {onBind}; // export {onBind};
/***/ }, /***/ },
/* 11 */ /* 14 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -777,11 +776,11 @@
var _desc, _value, _class; var _desc, _value, _class;
var _SelectedContainer2 = __webpack_require__(7); var _SelectedContainer2 = __webpack_require__(10);
var _SelectedContainer3 = _interopRequireDefault(_SelectedContainer2); var _SelectedContainer3 = _interopRequireDefault(_SelectedContainer2);
var _decorators = __webpack_require__(10); var _decorators = __webpack_require__(13);
var _decorators2 = _interopRequireDefault(_decorators); var _decorators2 = _interopRequireDefault(_decorators);
@ -862,7 +861,7 @@
exports.default = SelectedContainerCreate; exports.default = SelectedContainerCreate;
/***/ }, /***/ },
/* 12 */ /* 15 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -876,9 +875,9 @@
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _AbsBaseSelect2 = __webpack_require__(13); var _AbsBaseSelect2 = __webpack_require__(16);
var _NoTreeData = __webpack_require__(9); var _NoTreeData = __webpack_require__(12);
var _NoTreeData2 = _interopRequireDefault(_NoTreeData); var _NoTreeData2 = _interopRequireDefault(_NoTreeData);
@ -945,7 +944,7 @@
exports.default = NoTreeSelect; exports.default = NoTreeSelect;
/***/ }, /***/ },
/* 13 */ /* 16 */
/***/ function(module, exports) { /***/ function(module, exports) {
"use strict"; "use strict";
@ -1487,7 +1486,7 @@
exports.AbsBaseSelect = AbsBaseSelect; exports.AbsBaseSelect = AbsBaseSelect;
/***/ }, /***/ },
/* 14 */ /* 17 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -1501,9 +1500,9 @@
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _AbsBaseSelect2 = __webpack_require__(13); var _AbsBaseSelect2 = __webpack_require__(16);
var _DataTree = __webpack_require__(8); var _DataTree = __webpack_require__(11);
var _DataTree2 = _interopRequireDefault(_DataTree); var _DataTree2 = _interopRequireDefault(_DataTree);
@ -1612,7 +1611,7 @@
exports.default = TreeSelect; exports.default = TreeSelect;
/***/ }, /***/ },
/* 15 */ /* 18 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -1624,9 +1623,9 @@
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _AbsBaseSelect = __webpack_require__(13); var _AbsBaseSelect = __webpack_require__(16);
var _TreeSelect2 = __webpack_require__(14); var _TreeSelect2 = __webpack_require__(17);
var _TreeSelect3 = _interopRequireDefault(_TreeSelect2); var _TreeSelect3 = _interopRequireDefault(_TreeSelect2);
@ -1707,7 +1706,7 @@
exports.default = SingleTreeSelect; exports.default = SingleTreeSelect;
/***/ }, /***/ },
/* 16 */ /* 19 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -1721,9 +1720,9 @@
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _AbsBaseSelect2 = __webpack_require__(13); var _AbsBaseSelect2 = __webpack_require__(16);
var _NoTreeData = __webpack_require__(9); var _NoTreeData = __webpack_require__(12);
var _NoTreeData2 = _interopRequireDefault(_NoTreeData); var _NoTreeData2 = _interopRequireDefault(_NoTreeData);

@ -0,0 +1,7 @@
import {fileUploadInit} from './seeds/file_upload'
import {imageUploadInit} from './seeds/image_upload'
$(function () {
// fileUploadInit();
imageUploadInit();
});

@ -1,4 +1,4 @@
import fileUploadInit from './seeds/file_upload' import {fileUploadInit} from './seeds/file_upload'
import {extendedFieldInit} from './seeds/extended_field' import {extendedFieldInit} from './seeds/extended_field'
import {customCheckInit} from './seeds/custom_check' import {customCheckInit} from './seeds/custom_check'
import {readMoreInit} from './seeds/read_more' import {readMoreInit} from './seeds/read_more'

@ -0,0 +1,104 @@
import SelectedContainer from 'components/SelectedContainer';
import SelectedContainerCreate from 'components/SelectedContainerCreate';
import NoTreeSelect from 'components/NoTreeSelect';
import TreeSelect from 'components/TreeSelect';
import SingleTreeSelect from 'components/SingleTreeSelect'
import SelectOrCreate from 'components/SelectOrCreate'
$(function () {
function createSpecs(url) {
// SPECIALIZATIONS
let sb_main = new TreeSelect($('#select-box-1'), {url, visible: true, required: true});
sb_main.setHeader("Тип готовой работы");
let select_container = new SelectedContainer($('#selected-spec'),
{
obj: sb_main,
});
sb_main.connectSelectedContainer(select_container);
let sb_1 = new TreeSelect($('#select-box-2'), {obj: sb_main});
let sb_2 = new TreeSelect($('#select-box-3'), {obj: sb_main});
let sb_3 = new TreeSelect($('#select-box-4'), {obj: sb_main});
let sb_4 = new TreeSelect($('#select-box-5'), {obj: sb_main});
// select_container.on("add", () => {
// let $container = $('#spec-value');
// $container.html($('#selected-spec').find(".selected-element").find(".name").html());
// });
sb_main.setNearbySelectBox(sb_1);
sb_1.setNearbySelectBox(sb_2, sb_main);
sb_2.setNearbySelectBox(sb_3, sb_1);
sb_3.setNearbySelectBox(sb_4, sb_2);
sb_4.setNearbySelectBox("", sb_3);
}
function createBuildingClass(url) {
// BUILDING-CLASSIFICATION
sb_build_main = new TreeSelect($('#sb-building-classification'), {url, visible: true});
sb_build_main.setHeader("Классификация здания");
let sb_build_1 = new TreeSelect($('#sb-building-sub-classification'), {obj: sb_build_main});
let select_build_container = new SelectedContainer($('#selected-building-classification'),
{
obj: sb_build_main,
onlyOne: true
});
sb_build_main.connectSelectedContainer(select_build_container);
sb_build_main.setNearbySelectBox(sb_build_1);
sb_build_1.setNearbySelectBox("", sb_build_main);
}
function createConstructionType(url) {
sb_constr_main = new NoTreeSelect($('#sb-construction-type'), {url, visible: true});
sb_constr_main.setHeader("Вид строительства");
let select_constr_type = new SelectedContainer($('#selected-construction-type'), {
obj: sb_constr_main,
noTree: true,
onlyOne: true
});
sb_constr_main.connectSelectedContainer(select_constr_type);
}
function createLocations(url) {
sb_loc_main = new TreeSelect($('#sb-location-1'), {url, visible: true});
sb_loc_main.setHeader("Проектное местоположение");
let select_loc = new SelectedContainer($('#selected-location'),
{
obj: sb_loc_main,
onlyOne: true
});
sb_loc_main.connectSelectedContainer(select_loc);
let sb_loc_1 = new TreeSelect($('#sb-location-2'), {obj: sb_loc_main});
let sb_loc_2 = new TreeSelect($('#sb-location-3'), {obj: sb_loc_main});
sb_loc_main.setNearbySelectBox(sb_loc_1);
sb_loc_1.setNearbySelectBox(sb_loc_2, sb_loc_main);
sb_loc_2.setNearbySelectBox("", sb_loc_1);
}
function createFormat(url) {
let sb_format_main = new NoTreeSelect($('#sb-format'), {url, visible: true});
sb_format_main.setHeader("Формат электронной версии");
let select_format = new SelectedContainer($('#selected-format'), {
obj: sb_format_main,
noTree: true,
// onlyOne: true
});
sb_format_main.connectSelectedContainer(select_format);
}
let sb_loc_main, sb_constr_main, sb_build_main;
createSpecs('/api/specializations_flat');
createBuildingClass('/api/building_classifications');
createConstructionType('/api/construction_type');
createLocations('/api/locations_flat');
createFormat('/api/el_format');
// createRealty('/api/realties/current_user')
});

@ -1,24 +1,6 @@
function humanFileSize(bytes, si) { import {humanFileSize} from '../utils'
var thresh = si ? 1000 : 1024;
if (Math.abs(bytes) < thresh) function fileUploadInit() {
return bytes + ' B';
var units = si
? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
var u = -1;
do {
bytes /= thresh;
++u
} while (Math.abs(bytes) >= thresh && u < units.length - 1);
return bytes.toFixed(1) + ' ' + units[u]
}
export default function fileUploadInit() {
var $fileUploadContainer = $('#fileUploadContainer'); var $fileUploadContainer = $('#fileUploadContainer');
$('#fileUploadAddBtn').on('click', function ($evt) { $('#fileUploadAddBtn').on('click', function ($evt) {
@ -50,8 +32,6 @@ export default function fileUploadInit() {
$btn.closest('.file-upload-widget').remove() $btn.closest('.file-upload-widget').remove()
}); });
$fileUploadContainer.on('click', '.existing-file-remove-btn', function ($evt) {
var $btn = $(this);
$btn.closest('.existing-file-widget').remove()
});
} }
export {fileUploadInit}

@ -0,0 +1,47 @@
//TODO: оформить Upload'еры в виде классов
import {humanFileSize} from '../utils'
function imageUploadInit() {
var $fileUploadContainer = $('#fileUploadContainer');
$('#fileUploadAddBtn').on('click', function ($evt) {
$fileUploadContainer.find('.file-upload-widget').last().find('.file-upload-input').click()
});
$fileUploadContainer.on('change', '.file-upload-input', function ($evt) {
var $fileInput = $(this);
var $fileUploadWidget = $fileInput.closest('.file-upload-widget');
let $fileImg = $fileUploadWidget.find('img');
var filePath = $fileInput.val().replace(/\\/g, '/');
var fileName = path.basename(filePath);
var fileSize = $fileInput.get(0).files && humanFileSize($fileInput.get(0).files[0].size);
if (fileName) {
$fileUploadWidget.find('.file-upload-label').text(fileName + ' ' + fileSize);
var $newFileUploadWidget = $fileUploadWidget.clone();
$newFileUploadWidget.find('.file-upload-label').text('');
$fileUploadContainer.find('.list-new-new').append($newFileUploadWidget);
$fileUploadWidget.css('display', 'block');
if ($fileImg) {
let reader = new FileReader();
reader.onload = function (e) {
$fileImg.attr('src', e.target.result);
};
reader.readAsDataURL($fileInput[0].files[0]);
}
}
});
$fileUploadContainer.on('click', '.file-upload-remove-img-btn', function ($evt) {
var $btn = $(this);
$btn.closest('.file-upload-widget').remove()
});
}
export {imageUploadInit}

@ -0,0 +1,16 @@
function textareasMaxRowsInit() {
$('textarea[data-limit-rows=true]')
.on('keypress', function (event) {
console.log("work");
var textarea = $(this),
text = textarea.val(),
numberOfLines = (text.match(/\n/g) || []).length + 1,
maxRows = parseInt(textarea.attr('rows'));
if (event.which === 13 && numberOfLines === maxRows) {
return false;
}
});
}
export {textareasMaxRowsInit}

@ -0,0 +1,36 @@
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function humanFileSize(bytes, si) {
var thresh = si ? 1000 : 1024;
if (Math.abs(bytes) < thresh)
return bytes + ' B';
var units = si
? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
var u = -1;
do {
bytes /= thresh;
++u
} while (Math.abs(bytes) >= thresh && u < units.length - 1);
return bytes.toFixed(1) + ' ' + units[u]
}
export {humanFileSize, getCookie}

@ -38,7 +38,10 @@
.horizontal .horizontal
&.selected-container &.selected-container
display: inline-block //display: inline-block
max-width: 300px
.header, .name .header, .name
max-width: 300px //max-width: 300px
display: inline-block
.selected-element
max-width: 300px
display: inline-block

@ -20,7 +20,7 @@ label
margin-bottom: -1px margin-bottom: -1px
&:-webkit-autofill &:-webkit-autofill
-webkit-box-shadow: 0 0 0 1000px white inset -webkit-box-shadow: 0 0 0 1000px white inset
//transition: background-color 5000s ease-in-out 0s //transition: background-color 5000s ease-in-out 0s
&.icon-rub &.icon-rub
background: background:
image: url("#{$static}/img/rub.png") image: url("#{$static}/img/rub.png")
@ -135,6 +135,12 @@ textarea.description
width: auto width: auto
text-align: right text-align: right
.file-upload-widget
.preview
width: 100%
height: 200px
margin-bottom: 10px
.separator .separator
margin-top: 35px margin-top: 35px
margin-bottom: 15px margin-bottom: 15px
@ -209,14 +215,29 @@ textarea.description
color: darkgray color: darkgray
.file-upload-remove-btn .file-upload-remove-btn
display: inline-block display: inline-block
//position: absolute
width: 11px width: 11px
height: 11px height: 11px
background: url('#{$static}/img/delDoc.png') no-repeat center background: url('#{$static}/img/delDoc.png') no-repeat center
//background-size: cover
//right: -20px !important
//top: 2px
cursor: pointer cursor: pointer
.file-upload-remove-img-btn
width: 16px
height: 16px
background: url('#{$static}/img/aui-icon-close.png') no-repeat center
cursor: pointer
//padding: px
.preview-container
position: relative
display: inline-block
.file-upload-remove-img-btn
position: absolute
top: 0
right: 0
textarea.description
font-size: 9pt
color: darkgray
resize: vertical
max-height: 68px
.complete .complete
display: none display: none

@ -2,6 +2,7 @@ from django.contrib.contenttypes.models import ContentType
from rest_framework.serializers import ModelSerializer from rest_framework.serializers import ModelSerializer
from .models import Location from .models import Location
from work_sell.models import ElFormat
class NestedLocationSerializer(ModelSerializer): class NestedLocationSerializer(ModelSerializer):
@ -64,6 +65,19 @@ class LocationSerializerFlat(ModelSerializer):
'parent') 'parent')
class ElFormatSerializer(ModelSerializer):
# children = NestedLocationSerializerFlat(many=True)
# parent = NestedLocationSerializerFlat()
class Meta:
model = Location
fields = (
'id',
'name',
)
class ContentTypeSerializer(ModelSerializer): class ContentTypeSerializer(ModelSerializer):
class Meta: class Meta:
model = ContentType model = ContentType

@ -85,18 +85,18 @@
<div style="margin-top: 45px" class="row"> <div style="margin-top: 45px" class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<div class="simple-field"> <div class="simple-field">
<div class="header">Подобно опишите задание для / <div class="header">Подробно опишите задание для /
<span class="select-text" id="spec-value"></span> <span class="select-text" id="spec-value"></span>
</div> </div>
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i> <i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
<span class="required">Обязательно</span> <span class="required">Обязательно</span>
<textarea class="description" rows="6" placeholder= <textarea name="{{ form.description.html_name }}" class="description" rows="6" placeholder=
" Пример №1 " Пример №1
Разработать архиьектурные решения для жилого дома на основании эскизной проработки Разработать архиьектурные решения для жилого дома на основании эскизной проработки
Пример №2 Пример №2
Разработать проект по електроснабжению и освещению гаража"></textarea> Разработать проект по електроснабжению и освещению гаража">{{ form.description.value }}</textarea>
</div> </div>
<div class="documentsChat mod" id="fileUploadContainer"> <div class="documentsChat mod" id="fileUploadContainer">

@ -74,6 +74,20 @@ $static: '/static'
background-size: cover background-size: cover
background: url('#{$static}/img/listMain.png') no-repeat -48px 0 background: url('#{$static}/img/listMain.png') no-repeat -48px 0
.icon_tml span
content: ''
position: absolute
width: 27px
height: 24px
//left: -35px
top: 0
background: url('#{$static}/img/list4.png') no-repeat center !important
background-size: cover !important
.icon_tml:hover span
background: url('#{$static}/img/list4tml.png') no-repeat center !important
background-size: cover !important
.icon_tm1:hover span .icon_tm1:hover span
width: 26px width: 26px
background: url('#{$static}/img/listMain2.png') no-repeat left !important background: url('#{$static}/img/listMain2.png') no-repeat left !important
@ -92,6 +106,42 @@ $static: '/static'
background-size: cover background-size: cover
background-position: -49px 0 !important background-position: -49px 0 !important
.rating
width: 46px
height: 46px
float: right
border-radius: 100%
background-color: #4D4D4D
margin: 15px 0 0 10px
position: relative
.ratingInset
width: 46px
height: 46px
border-radius: 100%
background-color: #FF0027
position: absolute
/*left:-1.859px;*/
/*bottom: 3px;*/
clip: rect(0, 22px, 50px, 0)
transform: rotate(-90deg)
.iconRating
width: 100%
height: 100%
position: absolute
left: 0
top: 0
background: url('#{$static}/img/button12.png') no-repeat center
.ratingPer
color: #ff2c2c
font-size: 18px
font-family: 'pfdintextcomppro-regular', sans-serif
float: right
margin: 28px 0 0 9px
cursor: pointer
.mainMenu li .mainMenu li
&:last-child &:last-child
padding-right: 0 padding-right: 0
@ -111,6 +161,15 @@ $static: '/static'
&.icon_tm3.active span &.icon_tm3.active span
background: url('#{$static}/img/listMain2.png') no-repeat right !important background: url('#{$static}/img/listMain2.png') no-repeat right !important
li.officeList.icon_tml > a > p
display: inline-block
padding: 5px 7px 3px 7px
background: #ff0000
border-radius: 35px
position: absolute
right: -34px
top: -4px
.changeBlock .changeBlock
width: 485px width: 485px
overflow: hidden overflow: hidden

@ -247,43 +247,25 @@
</div> </div>
</div> </div>
<div id="tab12" class="tab-pane fade"> <div id="tab12" class="tab-pane fade">
{% if contractor.pk == request.user.pk %} {% if contractor.pk == request.user.pk %}
<div class="col-lg-9"> <div class="col-lg-9">
<p class="addWork"> <p class="addWork">
<a href="#" data-toggle="modal" data-target="#worksell-modal">Добавить проект</a> <a href="{% url 'work_sell:create'%}">Добавить проект</a>
</p> </p>
</div> </div>
<div id="worksell-modal" class="modal fade"> {# <div id="worksell-modal" class="modal fade">#}
<div class="modal-dialog" style="width: 900px;"> {# <div class="modal-dialog" style="width: 900px;">#}
<div class="modal-content"> {# <div class="modal-content">#}
<div class="modal-header"> {# <div class="modal-header">#}
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> {# <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>#}
<h4 class="modal-title">Добавить готовую работу</h4> {# <h4 class="modal-title">Добавить готовую работу</h4>#}
</div> {# </div>#}
{##}
{% include 'worksell_create_form.html' %} {# {% include 'worksell_create_form.html' %}#}
</div> {# </div>#}
</div> {# </div>#}
</div> {# </div>#}
{% endif %} {% endif %}
<div class="galleryWork2 disTab -work-sells-container"> <div class="galleryWork2 disTab -work-sells-container">
@ -817,7 +799,7 @@
data: dataSerializer, data: dataSerializer,
dataType: 'json', dataType: 'json',
success: function (data) { success: function (data) {
console.log(data); consoCoole.log(data);
if (data.status == 'ok') { if (data.status == 'ok') {
$("#resume-text-out").html(data.text); $("#resume-text-out").html(data.text);
$("#resume-text-edit").modal('hide'); $("#resume-text-edit").modal('hide');

@ -8,9 +8,12 @@ module.exports = {
// context: path.join(__dirname, "static", "js"), // context: path.join(__dirname, "static", "js"),
entry: { entry: {
// user: "./user", // projects
create_project: "./assets/js/src/customer_project_create.js", create_project: "./assets/js/src/customer_project_create.js",
init_customer_project_create: './assets/js/src/init_customer_project_create.js' init_customer_project_create: './assets/js/src/init_customer_project_create.js',
//worksell
create_worksell: "./assets/js/src/create_worksell.js",
init_create_worksell: './assets/js/src/init_create_worksell.js',
}, },

@ -1,7 +1,8 @@
from django.contrib import admin from django.contrib import admin
from .models import WorkSell, WorkSellPhoto, Picture from .models import WorkSell, WorkSellPhoto, Picture, ElFormat
admin.site.register(WorkSell) admin.site.register(WorkSell)
admin.site.register(ElFormat)
admin.site.register(Picture) admin.site.register(Picture)
admin.site.register(WorkSellPhoto) admin.site.register(WorkSellPhoto)

@ -20,26 +20,26 @@ class ContractorWorkSellTrashForm(forms.Form):
class WorkSellForm(forms.ModelForm): class WorkSellForm(forms.ModelForm):
# Define a form field manually for a reverse model vield: # Define a form field manually for a reverse model vield:
photos = forms.ModelMultipleChoiceField( # photos = forms.ModelMultipleChoiceField(
queryset=WorkSellPhoto.objects.none(), # queryset=WorkSellPhoto.objects.none(),
widget=forms.CheckboxSelectMultiple, # widget=forms.CheckboxSelectMultiple,
required=False, # required=False,
) # )
#
live_images = forms.ModelMultipleChoiceField( # live_images = forms.ModelMultipleChoiceField(
queryset=LiveImageUpload.objects.all(), # queryset=LiveImageUpload.objects.all(),
widget=forms.CheckboxSelectMultiple, # widget=forms.CheckboxSelectMultiple,
required=False, # required=False,
) # )
#
building_classification = TreeNodeChoiceField( # building_classification = TreeNodeChoiceField(
BuildingClassfication.objects.exclude(name='_root'), # BuildingClassfication.objects.exclude(name='_root'),
widget=forms.Select(attrs={ # widget=forms.Select(attrs={
'class': 'selectpicker' # 'class': 'selectpicker'
}), # }),
required=False, # required=False,
level_indicator='', # level_indicator='',
) # )
class Meta: class Meta:
model = WorkSell model = WorkSell
@ -48,28 +48,45 @@ class WorkSellForm(forms.ModelForm):
'building_classification', 'building_classification',
'construction_type', 'construction_type',
'specialization', 'specialization',
'specializations',
'contractor', 'contractor',
'location',
'budget', 'budget',
'currency', 'currency',
'description', 'description',
'el_format',
'name', 'name',
'term', 'term',
'term_type', 'term_type',
'work_type',
) )
widgets = { # widgets = {
'construction_type': forms.Select(attrs={'class': 'selectpicker'}), # 'construction_type': forms.Select(attrs={'class': 'selectpicker'}),
'currency': forms.Select(attrs={'class': 'selectpicker'}), # 'currency': forms.Select(attrs={'class': 'selectpicker'}),
'term_type': forms.Select(attrs={'class': 'selectpicker'}), # 'term_type': forms.Select(attrs={'class': 'selectpicker'}),
'work_type': forms.Select(attrs={'class': 'selectpicker -project-work-type-select-field'}), # 'work_type': forms.Select(attrs={'class': 'selectpicker -project-work-type-select-field'}),
} # }
# def clean(self):
# print("CLEAN", self.cleaned_data)
# data = self.cleaned_data.get('specialization')
# print("before data = ", data)
# # print('spec = ', data.split(','))
# # self.cleaned_data['specialization'] = data.split(',')
# super().clean()
# def clean_specialization(self):
# data = self.cleaned_data['specialization']
# print("before data = ", data)
# data = data.split(',')
# print("after data = ", data)
# return data
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
# self.request = kwargs.pop('request') self.request = kwargs.pop('request')
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.fields['photos'].queryset = self.instance.photos.all() # self.fields['photos'].queryset = self.instance.photos.all()
class WorkSellFilterForm(forms.ModelForm): class WorkSellFilterForm(forms.ModelForm):

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-12-06 21:34
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('work_sell', '0019_auto_20161201_2003'),
]
operations = [
migrations.CreateModel(
name='ElFormat',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=32)),
],
options={
'verbose_name': 'Формат электронной версии',
},
),
migrations.AddField(
model_name='worksell',
name='el_format',
field=models.ManyToManyField(blank=True, related_name='work_sell', to='work_sell.ElFormat'),
),
]

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-12-07 09:10
from __future__ import unicode_literals
from django.db import migrations, models
import mptt.fields
class Migration(migrations.Migration):
dependencies = [
('specializations', '0004_auto_20161014_2344'),
('work_sell', '0020_auto_20161207_0034'),
]
operations = [
migrations.AddField(
model_name='worksell',
name='specializations',
field=mptt.fields.TreeManyToManyField(blank=True, to='specializations.Specialization'),
),
migrations.AlterField(
model_name='worksell',
name='work_type',
field=models.IntegerField(blank=True, choices=[(403, 'Проектирование777'), (87, 'Техническое сопровождение666')], default=1),
),
]

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-12-07 09:13
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import mptt.fields
class Migration(migrations.Migration):
dependencies = [
('work_sell', '0021_auto_20161207_1210'),
]
operations = [
migrations.AlterField(
model_name='worksell',
name='building_classification',
field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='work_sells', to='projects.BuildingClassfication'),
),
migrations.AlterField(
model_name='worksell',
name='construction_type',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='work_sells', to='projects.ConstructionType'),
),
migrations.AlterField(
model_name='worksell',
name='location',
field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='work_sells', to='common.Location'),
),
migrations.AlterField(
model_name='worksell',
name='specialization',
field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='work_sells', to='specializations.Specialization'),
),
]

@ -1,5 +1,5 @@
from django.db import models from django.db import models
from mptt.models import TreeForeignKey from mptt.models import TreeForeignKey, TreeManyToManyField
from sorl.thumbnail import ImageField from sorl.thumbnail import ImageField
from projects.models import BuildingClassfication, ConstructionType, TERM_TYPES, CURRENCIES, Project from projects.models import BuildingClassfication, ConstructionType, TERM_TYPES, CURRENCIES, Project
@ -11,20 +11,23 @@ class WorkSell(models.Model):
# TODO: Add consistency ("work_sell" vs "worksell"): # TODO: Add consistency ("work_sell" vs "worksell"):
budget = models.DecimalField(max_digits=10, decimal_places=0, default=0, null=True, blank=True) budget = models.DecimalField(max_digits=10, decimal_places=0, default=0, null=True, blank=True)
building_classification = TreeForeignKey(BuildingClassfication, related_name='worksells', null=True, blank=True) building_classification = TreeForeignKey(BuildingClassfication, related_name='work_sells', null=True, blank=True)
construction_type = models.ForeignKey(ConstructionType, related_name='worksells', null=True, blank=True) construction_type = models.ForeignKey(ConstructionType, related_name='work_sells', null=True, blank=True)
contractor = models.ForeignKey(User, related_name='work_sell', null=True, contractor = models.ForeignKey(User, related_name='work_sell', null=True,
blank=True) # TODO: Pluralize related name blank=True) # TODO: Pluralize related name
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
currency = models.CharField(max_length=20, default='rur', choices=CURRENCIES, null=True, blank=True) currency = models.CharField(max_length=20, default='rur', choices=CURRENCIES, null=True, blank=True)
description = models.TextField(blank=True) description = models.TextField(blank=True)
location = TreeForeignKey('common.Location', related_name='worksells', null=True, blank=True) el_format = models.ManyToManyField('ElFormat', related_name='work_sell', blank=True)
location = TreeForeignKey('common.Location', related_name='work_sells', null=True, blank=True)
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
specialization = TreeForeignKey(Specialization, related_name='worksells', null=True, blank=True) # deprecated
specialization = TreeForeignKey(Specialization, related_name='work_sells', null=True, blank=True)
specializations = TreeManyToManyField(Specialization, blank=True)
team = models.ForeignKey(Team, related_name='work_sells', null=True, blank=True) team = models.ForeignKey(Team, related_name='work_sells', null=True, blank=True)
term = models.IntegerField(default=0, null=True, blank=True) term = models.IntegerField(default=0, null=True, blank=True)
term_type = models.CharField(max_length=20, choices=TERM_TYPES, default='hour', null=True, blank=True) term_type = models.CharField(max_length=20, choices=TERM_TYPES, default='hour', null=True, blank=True)
work_type = models.IntegerField(default=1, choices=Project.WORK_TYPES) work_type = models.IntegerField(default=1, choices=Project.WORK_TYPES, blank=True)
def __str__(self): def __str__(self):
return self.name return self.name
@ -80,3 +83,13 @@ class Picture(models.Model):
def delete(self, *args, **kwargs): def delete(self, *args, **kwargs):
self.file.delete(False) self.file.delete(False)
super().delete(*args, **kwargs) super().delete(*args, **kwargs)
class ElFormat(models.Model):
name = models.CharField(max_length=32)
def __str__(self):
return self.name
class Meta:
verbose_name = 'Формат электронной версии'

@ -1,55 +1,224 @@
{% extends 'partials/base.html' %} {% extends 'partials/base.html' %}
{% block content %} {% load staticfiles %}
<form method="post" enctype="multipart/form-data">{% csrf_token %} {% load sass_tags %}
{% load thumbnail %}
{% block old_css %}{% endblock %}
{% block head_css %}
<link rel='stylesheet' href='{% static "css/font-awesome.min.css" %}'>
<link rel='stylesheet' href='{% sass_src "sass/main.sass" %}'>
<link rel='stylesheet' href='{% sass_src "sass/components/custom-components.sass" %}'>
<link rel='stylesheet' href='{% sass_src "lib/proekton-components/sass/components.sass" %}'>
{# <style>#}
{# .-live-image-upload-container .-position-relative-parent {#}
{# position: relative#}
{# }#}
{##}
{# .-live-image-upload-container .-image-delete,#}
{# .-live-image-upload-container .-live-image-delete {#}
{# position: absolute;#}
{# top: 0;#}
{# right: 0;#}
{# background-color: white;#}
{# }#}
{# </style>#}
{% endblock %}
<div class="col-lg-7"> {% block content %}
<!-- The fileinput-button span is used to style the file input field as button --> {% include 'partials/modals/project_work_type_suggestion.html' %}
<span class="btn btn-success fileinput-button"> {% include 'partials/header.html' %}
<i class="glyphicon glyphicon-plus"></i> <div class="container main-scope">
<span>Add files...</span> <div class="row title-scope">
<input type="file" name="files[]" multiple> <div class="col-lg-12">
</span> {# <div class="title-scope">#}
<h1>Добавить готовую работу</h1>
{# </div>#}
</div>
</div> </div>
<input type="submit" value="Save12"/> <div class="row main-content">
</form> <div class="col-lg-12">
{% endblock %} <form action="{% url 'work_sell:create' %}" method="POST"
enctype="multipart/form-data" novalidate>
{% csrf_token %}
<div class="row">
<div class="col-lg-9">
<div class="simple-field">
<div class="header">Название проекта</div>
<i class="fa fa-question-circle-o" aria-hidden="true"></i>
<span class="required">Обязательно</span>
<input value="{{ form.name.value }}" name="{{ form.name.html_name }}"
class="simple-input italic"
placeholder="Пример: Дизайн проект квартиры, Армирование фундамента, Конструкции перекрытия и т.д."
autocomplete="off"
required>
</div>
</div>
<div class="col-lg-3">
<div class="header ">Стоимость готового проекта
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</div>
<input name="{{ form.budget.html_name }}" class="simple-input icon-rub js-number-format"
placeholder="Введите сумму"
value="{{ form.budget.value }}"
autocomplete="off">
</div>
</div>
<div class="row vertical-child mod-align-bottom">
<div class="col-lg-9">
<div class="" id="select-box-1"></div>
</div>
<div class="col-lg-3">
<div href="#" onclick="return false" data-toggle="modal"
data-target="#projectWorkTypeSuggestionModal"
class="btn btn-simple btn-plus">Нет нужной специальности хочу добавить
</div>
</div>
</div>
<div class="row">
<div class="col-lg-3">
<div class="vertical-child" id="select-box-2">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="select-box-3">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="select-box-4">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="select-box-5">
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12 vertical-child">
<div class="selected-container horizontal" id="selected-spec">
<input type="hidden" name="{{ form.specializations.html_name }}"
value="{{ form.specializations.value }}">
</div>
</div>
</div>
<div style="margin-top: 45px" class="row">
<div class="col-lg-12">
<div class="simple-field">
<div class="header">Подробно опишите проект
<span class="select-text" id="spec-value"></span>
</div>
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
<span class="required">Обязательно</span>
<textarea name="{{ form.description.html_name }}" class="description" rows="8">{{ form.description.value }}</textarea>
{% block js_block %} </div>
<div class="documentsChat mod" id="fileUploadContainer">
<div style="display: inline-block;vertical-align: middle;">
<div style="display: inline-block;vertical-align: inherit;"
class="upload-new paper-clip">
<p id="fileUploadAddBtn" style="margin: 0">прикрепить файл</p>
</div>
<span style="display: inline-block;vertical-align: inherit;">ДО 100 ФАЙЛОВ</span>
</div>
<script type="text/javascript"> <div class="row list-new-new" style="margin-top: 10px">
<div class="col-lg-3 file-upload-widget" style="display: none">
<input type="file" name="new_files" class="file-upload-input"
style="position: absolute; top: -1000px; left: -1000px">
<div class="preview-container">
<div class="file-upload-remove-img-btn"></div>
<img class="preview" src="#" alt="your image"/>
<textarea rows="2" data-limit-rows="true" class="description">
$(function(){ </textarea>
$.ajax({ </div>
url : '/work_sell/test/', <span style="display:none" class="file-upload-label"></span>
success:function(data){
alert(data);
console.log(data);
}
});
});
{# $(function(){#} </div>
{# var files;#} </div>
{# $('input[type=file]').on('change', prepareUpload);#} </div>
{# $('form').on('submit', uploadFiles);#} </div>
{##} </div>
{# function uploadFiles(e){#} <div class="row">
{# console.log('submit');#} <div class="col-lg-3">
{# e.stopPropagation();#} <div class="vertical-child" id="sb-building-classification">
{# e.preventDefault();#} </div>
{# var data = new FormData();#} <div class="vertical-child" id="sb-building-sub-classification">
{# $.each(files, function(k,v){#} </div>
{# console.log(k);#} <div class="selected-container" id="selected-building-classification">
{# console.log(v);#} <input type="hidden"
{# data.append(k, v);#} name="{{ form.building_classification.html_name }}"
{# });#} value="{{ form.building_classification.value }}">
{# console.log(data);#} </div>
{# }#} </div>
{# function prepareUpload(e){#} <div class="col-lg-3">
{# files = e.target.files;#} <div class="vertical-child" id="sb-construction-type">
{# }#} </div>
{##} <div class="selected-container" id="selected-construction-type">
{# });#} <input type="hidden"
</script> name="{{ form.construction_type.html_name }}"
value="{{ form.construction_type.value }}">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="sb-location-1"></div>
<div class="vertical-child" id="sb-location-2"></div>
<div class="vertical-child" id="sb-location-3"></div>
<div class="selected-container" id="selected-location">
<input type="hidden"
name="{{ form.location.html_name }}"
value="{{ form.location.value }}">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="sb-format"></div>
<div class="selected-container" id="selected-format">
<input type="hidden"
name="{{ form.el_format.html_name }}"
value="{{ form.el_format.value }}">
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="separator">
<div class="border"></div>
</div>
</div>
</div>
<div class="row top-line">
<div class="col-lg-3" style="text-align: center">
<div class="header">&nbsp;</div>
<input style="width: 100%" type="submit" class="btn btn-simple"
value="РАЗМЕСТИТЬ ЗАКАЗ">
</div>
<div class="col-lg-3 col-lg-offset-6" style="text-align: center">
<div class="header">&nbsp;</div>
<input style="width: 100%" type="button" class="btn btn-simple"
value="ПРЕДВАРИТЕЛЬНЫЙ ПРОСМОТР">
</div>
</div>
</form>
</div>
</div>
{% include 'partials/footer.html' %}
</div>
{% endblock %}
{% block old_js %}
<script src='{% static "lib/jquery.fileupload/js/vendor/jquery.ui.widget.js" %}'></script>
<script src='{% static "lib/jquery.fileupload/js/jquery.iframe-transport.js" %}'></script>
<script src='{% static "lib/jquery.fileupload/js/jquery.fileupload.js" %}'></script>
<script src='{% static "lib/jquery.fileupload/js/jquery.fileupload-process.js" %}'></script>
<script src='{% static "lib/lodash/lodash.js" %}'></script>
<script src='{% static "my-libs.js" %}'></script>
{% endblock %} {% endblock %}
{% block js_block %}
<script src='{% static "js/bootstrap.min.js" %}'></script>
<script src='{% static "js/build/init_create_worksell.js" %}'></script>
<script src='{% static "js/build/create_worksell.js" %}'></script>
<script src='{% static "js/jquery.mask.min.js" %}'></script>
<script>
$(function () {
$('.js-number-format').mask('0000000000');
})
</script>
{% endblock %}

@ -5,7 +5,8 @@ from .views import (
WorkSellUpdateView, WorkSellUpdateView,
WorkSellDeleteView, WorkSellDeleteView,
UploadView, UploadView,
work_sell_create, # work_sell_create,
WorkSellCreateView,
BasicCreateView, BasicCreateView,
PictureCreateView, PictureCreateView,
ContractorWorkSellTrashView, ContractorWorkSellTrashView,
@ -17,12 +18,12 @@ app_name = 'work_sell'
urlpatterns = [ urlpatterns = [
urls.url(r'^$', WorkSellFilterView.as_view(), name='list'), urls.url(r'^$', WorkSellFilterView.as_view(), name='list'),
# urls.url(r'^create/$', WorkSellCreateView.as_view(), name='create'), urls.url(r'^create/$', WorkSellCreateView.as_view(), name='create'),
urls.url(r'^upload/$', UploadView.as_view(), name='upload'), urls.url(r'^upload/$', UploadView.as_view(), name='upload'),
urls.url(r'^(?P<pk>\d+)/edit/$', WorkSellUpdateView.as_view(), name='edit'), urls.url(r'^(?P<pk>\d+)/edit/$', WorkSellUpdateView.as_view(), name='edit'),
urls.url(r'^(?P<pk>\d+)/delete/$', WorkSellDeleteView.as_view(), name='delete'), urls.url(r'^(?P<pk>\d+)/delete/$', WorkSellDeleteView.as_view(), name='delete'),
urls.url(r'^(?P<pk>\d+)/trash/$', ContractorWorkSellTrashView.as_view(), name='contractor-worksell-trash'), urls.url(r'^(?P<pk>\d+)/trash/$', ContractorWorkSellTrashView.as_view(), name='contractor-worksell-trash'),
urls.url(r'^create/$', work_sell_create, name='create'), # urls.url(r'^create/$', work_sell_create, name='create'),
urls.url(r'^basic/$', BasicCreateView.as_view(), name='upload-basic'), urls.url(r'^basic/$', BasicCreateView.as_view(), name='upload-basic'),
urls.url(r'^new/$', PictureCreateView.as_view(), name='upload-new'), urls.url(r'^new/$', PictureCreateView.as_view(), name='upload-new'),
urls.url(r'^(?P<pk>\d+)/$', WorkSellDetail.as_view(), name='detail'), urls.url(r'^(?P<pk>\d+)/$', WorkSellDetail.as_view(), name='detail'),

@ -12,13 +12,15 @@ from django.contrib import messages
from django.db.models import Q from django.db.models import Q
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.exceptions import PermissionDenied
from django.http import JsonResponse, HttpResponse, HttpResponseForbidden from django.http import JsonResponse, HttpResponse, HttpResponseForbidden
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.views.generic import ListView, DetailView, CreateView, View, \ from django.views.generic import ListView, DetailView, CreateView, View, \
UpdateView, DeleteView, TemplateView UpdateView, DeleteView, TemplateView
from projects.models import BuildingClassfication, ConstructionType from projects.models import BuildingClassfication, ConstructionType
from .models import WorkSell, Picture, WorkSellPhoto from projects.forms import ProjectWorkTypeSuggestionForm
from .models import WorkSell, Picture, WorkSellPhoto, WorkSellPhoto
from .forms import WorkSellForm, WorkSellFilterForm, ContractorWorkSellTrashForm from .forms import WorkSellForm, WorkSellFilterForm, ContractorWorkSellTrashForm
from .serialize import serialize from .serialize import serialize
from .response import JSONResponse, response_mimetype from .response import JSONResponse, response_mimetype
@ -143,33 +145,83 @@ class WorkSellDetail(DetailView):
return context return context
def work_sell_create(request): # def work_sell_create(request):
if request.is_ajax(): # if request.is_ajax():
form = WorkSellForm(data=request.POST) # form = WorkSellForm(data=request.POST)
# if form.is_valid():
# instance = form.save(commit=False)
# # import code; code.interact(local=dict(globals(), **locals()))
# instance.save()
# form.save_m2m()
# images_ids = request.POST.get('images-ids').split(';')[:-1]
# for pk in images_ids:
# picture = Picture.objects.get(pk=pk)
# temp_file = ContentFile(picture.file.read())
# temp_file.name = picture.file.name
# w_photo = WorkSellPhoto()
# w_photo.img = temp_file
# w_photo.worksell = instance
# w_photo.save()
# data = {'status': 'ok'}
# else:
# data = {'status': 'no', 'form_errors': form.errors}
# return HttpResponse(json.dumps(data), content_type='application/json')
class WorkSellCreateView(BaseMixin, View):
model = WorkSell
form_class = WorkSellForm
work_type_suggestion_form = ProjectWorkTypeSuggestionForm
template_name = 'worksell_create.html'
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_contractor():
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
def get(self, request, *args, **kwargs):
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
form = self.form_class(request=request)
work_type_suggestion_form = self.work_type_suggestion_form(request=request, prefix='work_type_suggestion')
context.update({
'form': form,
'work_type_suggestion_form': work_type_suggestion_form,
})
return render(request, self.template_name, context)
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST, request=request) # Passing `request.FILES` seems unnecessary here. Files are added manually below
# TODO: fix it on front
request.POST.setlist('specializations', request.POST.get('specializations').split(','))
request.POST.setlist('el_format', request.POST.get('el_format').split(','))
print("POST before = ", request.POST)
if form.is_valid(): if form.is_valid():
instance = form.save(commit=False) work_sell = form.save(commit=False)
# import code; code.interact(local=dict(globals(), **locals())) work_sell.contractor = request.user
instance.save() work_sell.save()
form.save_m2m() form.save_m2m()
images_ids = request.POST.get('images-ids').split(';')[:-1]
for pk in images_ids:
picture = Picture.objects.get(pk=pk)
temp_file = ContentFile(picture.file.read())
temp_file.name = picture.file.name
w_photo = WorkSellPhoto()
w_photo.img = temp_file
w_photo.worksell = instance
w_photo.save()
data = {'status': 'ok'}
else:
data = {'status': 'no', 'form_errors': form.errors}
return HttpResponse(json.dumps(data), content_type='application/json')
for file in request.FILES.getlist('new_files'):
WorkSellPhoto.objects.create(img=file, worksell=work_sell)
class WorkSellCreateView(CreateView): messages.info(request, 'Работа успешно создана')
model = WorkSell redirect_to = reverse('work_sell:detail', kwargs={'pk': work_sell.pk})
form_class = WorkSellForm return redirect(redirect_to)
template_name = 'worksell_create.html' else:
if form.errors:
messages.info(request, (
'<p>Произошла ошибка (form)</p>'
'<pre>{form}</pre>'
).format(form=pformat(form.errors)))
context = self.get_context_data(**kwargs)
context.update({'form': form})
# context.update({'photos': WorkSellPhoto.objects.filter(worksell__id=)})
return render(request, self.template_name, context)
class WorkSellUpdateView(UpdateView): class WorkSellUpdateView(UpdateView):

Loading…
Cancel
Save