diff --git a/archilance/management/commands/generate_projects.py b/archilance/management/commands/generate_projects.py index 620c680..febb7cd 100644 --- a/archilance/management/commands/generate_projects.py +++ b/archilance/management/commands/generate_projects.py @@ -47,7 +47,7 @@ class Command(BaseCommand): # ('id', 'Relation? False', 'Null? False', 'Blank? True', 'Hidden? False'), # ('price_and_term_required', 'Relation? False', 'Null? False', 'Blank? True', 'Hidden? False'), # ('text', 'Relation? False', 'Null? False', 'Blank? True', 'Hidden? False'), - + diff --git a/archilance/mixins.py b/archilance/mixins.py index 35eef9a..a2645d2 100644 --- a/archilance/mixins.py +++ b/archilance/mixins.py @@ -1,3 +1,4 @@ +from django.conf import settings from django.contrib.sites.models import Site from django.views.generic.base import ContextMixin @@ -16,6 +17,8 @@ class BaseMixin(ContextMixin): c['domain'] = Site.objects.get_current().domain + c['TEMPLATE_DEBUG'] = settings.TEMPLATE_DEBUG + return c diff --git a/archilance/settings/base.py b/archilance/settings/base.py index 8eeb4dc..96d7bd5 100644 --- a/archilance/settings/base.py +++ b/archilance/settings/base.py @@ -12,6 +12,7 @@ SECRET_KEY = 'vb6@b9zj7^f!^+x*e8=e!oundyu1!e*&0i(3gu2xwo4%fx4h&n' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True +TEMPLATE_DEBUG = True # Show debug info in templates. See `projects/templates/project_filter.html` ALLOWED_HOSTS = [] diff --git a/assets/index.js b/assets/index.js index 896f1fa..acfb8c5 100644 --- a/assets/index.js +++ b/assets/index.js @@ -3,7 +3,7 @@ var $specSelects = $('.-spec-select') var specSelectOptions = { language: 'ru', //minimumInputLength: 1, // Commented out to immediately load remote data - placeholder: '', // Required by `allowClear` + placeholder: 'Выберите специализацию', // Required by `allowClear` allowClear: true, ajax: { @@ -52,8 +52,7 @@ if (chosenSpecId) updateSpecializationWidgets(chosenSpecId) $specSelects.on('change', function($evt) { - var specId = $evt.added.id - updateSpecializationWidgets(specId) + updateSpecializationWidgets($evt.added ? $evt.added.id : null) }) @@ -94,7 +93,7 @@ var $locationSelects = $('.-location-select') var locationSelectOptions = { language: 'ru', - placeholder: '', // Required by `allowClear` + placeholder: 'Выберите местоположение', // Required by `allowClear` allowClear: true, } @@ -119,8 +118,7 @@ getLocationTree(null).then(function(locs) { $locationSelects.on('change', function($evt) { - var locId = $evt.added.id - updateLocationWidgets(locId) + updateLocationWidgets($evt.added ? $evt.added.id : null) }) @@ -244,67 +242,70 @@ function getSpecializationTree(specId) { var specs = { specLevel1: null, specLevel2: null, specLevel3: null, specLevel4: null, } - - return $.ajax({url: '/api/specializations/' + specId + '/', method: 'GET', dataType: 'json'}) - .then(function(spec) { - if (spec.level === 1) { - return _.merge(specs, {specLevel1: spec}) - } else if (spec.level === 2) { - var specLevel2 = spec - - return $.ajax({url: '/api/specializations/' + specLevel2.parent.id + '/', method: 'GET', dataType: 'json'}) - .then(function(spec) { - var specLevel1 = spec - - return _.merge(specs, { - specLevel1: specLevel1, - specLevel2: specLevel2, + if (specId === null) { + return $.when(specs) + } else { + return $.ajax({url: '/api/specializations/' + specId + '/', method: 'GET', dataType: 'json'}) + .then(function(spec) { + if (spec.level === 1) { + return _.merge(specs, {specLevel1: spec}) + } else if (spec.level === 2) { + var specLevel2 = spec + + return $.ajax({url: '/api/specializations/' + specLevel2.parent.id + '/', method: 'GET', dataType: 'json'}) + .then(function(spec) { + var specLevel1 = spec + + return _.merge(specs, { + specLevel1: specLevel1, + specLevel2: specLevel2, + }) }) - }) - } else if (spec.level === 3) { - var specLevel3 = spec - - return $.ajax({url: '/api/specializations/' + specLevel3.parent.id + '/', method: 'GET', dataType: 'json'}) - .then(function(spec) { - var specLevel2 = spec - - return $.ajax({url: '/api/specializations/' + specLevel2.parent.id + '/', method: 'GET', dataType: 'json'}) - .then(function(spec) { - var specLevel1 = spec - - return _.merge(specs, { - specLevel1: specLevel1, - specLevel2: specLevel2, - specLevel3: specLevel3, + } else if (spec.level === 3) { + var specLevel3 = spec + + return $.ajax({url: '/api/specializations/' + specLevel3.parent.id + '/', method: 'GET', dataType: 'json'}) + .then(function(spec) { + var specLevel2 = spec + + return $.ajax({url: '/api/specializations/' + specLevel2.parent.id + '/', method: 'GET', dataType: 'json'}) + .then(function(spec) { + var specLevel1 = spec + + return _.merge(specs, { + specLevel1: specLevel1, + specLevel2: specLevel2, + specLevel3: specLevel3, + }) }) - }) - }) - } else if (spec.level === 4) { - var specLevel4 = spec - - return $.ajax({url: '/api/specializations/' + specLevel4.parent.id + '/', method: 'GET', dataType: 'json'}) - .then(function(spec) { - var specLevel3 = spec - - return $.ajax({url: '/api/specializations/' + specLevel3.parent.id + '/', method: 'GET', dataType: 'json'}) - .then(function(spec) { - var specLevel2 = spec - - return $.ajax({url: '/api/specializations/' + specLevel2.parent.id + '/', method: 'GET', dataType: 'json'}) - .then(function(spec) { - var specLevel1 = spec - - return _.merge(specs, { - specLevel1: specLevel1, - specLevel2: specLevel2, - specLevel3: specLevel3, - specLevel4: specLevel4, + }) + } else if (spec.level === 4) { + var specLevel4 = spec + + return $.ajax({url: '/api/specializations/' + specLevel4.parent.id + '/', method: 'GET', dataType: 'json'}) + .then(function(spec) { + var specLevel3 = spec + + return $.ajax({url: '/api/specializations/' + specLevel3.parent.id + '/', method: 'GET', dataType: 'json'}) + .then(function(spec) { + var specLevel2 = spec + + return $.ajax({url: '/api/specializations/' + specLevel2.parent.id + '/', method: 'GET', dataType: 'json'}) + .then(function(spec) { + var specLevel1 = spec + + return _.merge(specs, { + specLevel1: specLevel1, + specLevel2: specLevel2, + specLevel3: specLevel3, + specLevel4: specLevel4, + }) }) - }) - }) - }) - } - }) + }) + }) + } + }) + } } diff --git a/common/templates/templatetags/inspect.html b/common/templates/templatetags/inspect_.html similarity index 100% rename from common/templates/templatetags/inspect.html rename to common/templates/templatetags/inspect_.html diff --git a/common/templatetags/common_tags.py b/common/templatetags/common_tags.py index 1f76ddd..502febf 100644 --- a/common/templatetags/common_tags.py +++ b/common/templatetags/common_tags.py @@ -5,14 +5,14 @@ import os register = template.Library() -@register.inclusion_tag('templatetags/inspect.html', takes_context=True) -def inspect(context, obj): - return {'obj': pformat(obj.__dict__)} +# @register.inclusion_tag('templatetags/inspect.html', takes_context=True) +# def inspect(context, obj): +# return {'obj': pformat(obj.__dict__)} -@register.inclusion_tag('templatetags/inspect.html', takes_context=True) -def inspect2(context, obj): - return {'obj': pformat(dir(obj))} +@register.filter('inspect') +def inspect(obj): + return pformat(obj.__dict__) @register.simple_tag diff --git a/projects/forms.py b/projects/forms.py index fa0b5b9..f17c2f8 100644 --- a/projects/forms.py +++ b/projects/forms.py @@ -2,6 +2,8 @@ from django import forms from django.db.models import Q from django.forms.models import inlineformset_factory from mptt.forms import TreeNodeChoiceField +from pprint import pprint, pformat +import itertools from .models import Project, ProjectFile, Portfolio, Answer, Realty, PortfolioPhoto, Stage, Specialization from common.models import Location @@ -11,8 +13,59 @@ from users.models import User # RealtyFormSet = inlineformset_factory(Project, Realty) -class ProjectsForm(forms.Form): - name = forms.CharField(max_length=255) +class ProjectFilterForm(forms.ModelForm): + class Meta: + model = Project + + fields = ( + 'cro', + 'work_type', + 'specialization', + ) + + widgets = { + 'work_type': forms.Select(attrs={'class': 'selectpicker'}), + } + + def __init__(self, *args, **kwargs): + self.request = kwargs.pop('request') + super().__init__(*args, **kwargs) + + self.fields['work_type'].choices = tuple(itertools.chain((('',''),), self.fields['work_type'].choices)) + self.fields['work_type'].required = False + self.fields['work_type'].initial = '' + + self.fields['specialization'].required = False + + self.fields['specialization'].queryset = Specialization.objects.root_nodes()[0].get_descendants() + + +class ProjectFilterRealtyForm(forms.ModelForm): + class Meta: + model = Realty + + fields = ( + 'building_classification', + 'construction_type', + 'location', + ) + + widgets = { + 'building_classification': forms.Select(attrs={'class': 'selectpicker'}), + 'construction_type': forms.Select(attrs={'class': 'selectpicker'}), + } + + def __init__(self, *args, **kwargs): + self.request = kwargs.pop('request') + super().__init__(*args, **kwargs) + + self.fields['building_classification'].empty_label = '' + self.fields['building_classification'].required = False + + self.fields['construction_type'].empty_label = '' + self.fields['construction_type'].required = False + + self.fields['location'].queryset = Location.objects.root_nodes()[0].get_descendants() class CustomerProjectEditForm(forms.ModelForm): @@ -52,9 +105,7 @@ class CustomerProjectEditForm(forms.ModelForm): super().__init__(*args, **kwargs) self.fields['realty'].empty_label = 'Создать новый' - self.fields['specialization'].queryset = Specialization.objects.root_nodes()[0].get_descendants() - self.fields['specialization'].widget.attrs = {'class': '-spec-select', 'style': 'width: 100%'} if self.instance.pk: self.fields['files'].queryset = self.instance.files @@ -168,3 +219,6 @@ class CustomerProjectDeleteForm(forms.Form): super().__init__(*args, **kwargs) self.fields['pk'].queryset = self.req.user.projects.filter(Q(state='active') | Q(state='trashed')) + + +# import code; code.interact(local=dict(globals(), **locals())) diff --git a/projects/templates/customer_project_create.html b/projects/templates/customer_project_create.html index 6452d41..b55e31c 100644 --- a/projects/templates/customer_project_create.html +++ b/projects/templates/customer_project_create.html @@ -83,19 +83,19 @@
Требуется допуск СРО
+ +Требуется допуск (СРО)
Биржа проектов
++ {{ proj }} +
+{{ proj.text }}
+ + {% if TEMPLATE_DEBUG %} +{{ proj|inspect }}
Specialization: {{ proj.specialization }}
Realty location: {{ proj.realty.location }}
Constr. type: {{ proj.realty.construction_type }}
Build. classif.: {{ proj.realty.building_classification }}
+ {% endif %}
+
+ + {{ proj.budget }} +
+Биржа проектов
-Расширенный поиск
- -Список проектов
-Сортировать по:
- - цене - - - - cорту - - - - рейтингу - - - - дате размещения - - - - ответам - - - - просмотрам - - -- {{ proj }} -
-{{ proj.text }}
-- {{ proj.budget }} -
-Произошла ошибка (form)
' + '{form}'
+ ).format(form=pformat(form.errors)))
+
+ if realty_form and realty_form.errors:
+ messages.info(request, (
+ 'Произошла ошибка (realty_form)
' + '{realty_form}'
+ ).format(realty_form=pformat(realty_form.errors)))
+
+ order_by = request.GET.get('order_by') # TODO: Validate
+
+ if order_by:
+ projects = projects.order_by(order_by)
+
+ projects = projects[:10]
+
+ context.update({
+ 'form': form,
+ 'realty_form': realty_form,
+ 'projects': projects,
+ 'display_msg': display_msg,
+ })
+
+ return render(request, self.template_name, context)
class ProjectView(BaseMixin, View):
@@ -335,4 +407,6 @@ class ContractorPortfolioUpdateView(UpdateView):
def get_success_url(self):
return reverse('proje')
+
+
# import code; code.interact(local=dict(globals(), **locals()))
diff --git a/templates/partials/base.html b/templates/partials/base.html
index 951b64f..12c8ad1 100644
--- a/templates/partials/base.html
+++ b/templates/partials/base.html
@@ -25,9 +25,7 @@
-
-
- {% endcompress %}
+{% endcompress %}
diff --git a/templates/partials/header.html b/templates/partials/header.html
index 573a7ca..7e002a7 100644
--- a/templates/partials/header.html
+++ b/templates/partials/header.html
@@ -9,7 +9,7 @@