remotes/origin/setup
ArturBaybulatov 10 years ago
parent 6048dc1f89
commit d1e49f6230
  1. 32
      archilance/management/commands/generate_teams.py
  2. 1
      archilance/settings/base.py
  3. 5
      requirements/base.txt
  4. 13
      users/forms.py
  5. 2
      users/models.py
  6. 310
      users/templates/contractor_filter.html
  7. 108
      users/views.py

@ -0,0 +1,32 @@
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.core.management import BaseCommand
from django.utils import timezone
import pydash as _; _.map = _.map_; _.filter = _.filter_
import random
from archilance import util
from common.models import Location
from specializations.models import Specialization
from users.models import User, GENDERS, Team
class Command(BaseCommand):
def handle(self, *args, **options):
print('---------------------------------------')
print('Generating teams...')
print('---------------------------------------')
# ('owner', 'Relation? True', 'Null? True', '(relation)', 'Hidden? False'),
# ('users', 'Relation? True', 'Null? False', '(relation)', 'Hidden? False'),
#
# ('name', 'Relation? False', 'Null? False', 'Blank? False', 'Hidden? False'),
contractors = User.contractor_objects.order_by('?')
contractors = contractors[:contractors.count() // 2]
for contr in contractors:
team = Team.objects.create(name="%s's team" % contr.username, owner=contr)
team.users = User.contractor_objects.filter(team=None)[:_.random(1, 4)]

@ -248,6 +248,7 @@ EMAIL_DEFAULT = 'noreply@archilance.ru'
SHELL_PLUS_POST_IMPORTS = ( # Extra auto imports
'natsort',
('archilance', 'util'),
('pprint', ('pprint', 'pformat')),
)

@ -36,7 +36,4 @@ six==1.10.0
sorl-thumbnail==12.3
sqlparse==0.1.19
tornado==4.3
natsort

@ -47,7 +47,13 @@ class ContractorFilterForm(forms.Form):
# ('created', 'дате размещения'),
# ('views', 'просмотрам'),
# )
#
PARTY_TYPES = (
('', 'Все'),
('teams', 'Группы'),
('contractors', 'Исполнители'),
)
# order_by = forms.ChoiceField(required=False, choices=PROJECT_ORDER_CHOICES)
# last_order_by = forms.ChoiceField(required=False, choices=PROJECT_ORDER_CHOICES)
# reverse_order = forms.BooleanField(required=False)
@ -84,6 +90,11 @@ class ContractorFilterForm(forms.Form):
cro = forms.BooleanField(required=False)
party_types = forms.ChoiceField(
choices=PARTY_TYPES,
required=False,
)
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
super().__init__(*args, **kwargs)

@ -15,7 +15,6 @@ GENDERS = (
class UserManager(BaseUserManager):
def create_user(self, username, email, password=None, **kwargs):
# import code; code.interact(local=dict(globals(), **locals()))
if not email:
raise ValueError('Users must have an email address')
@ -77,6 +76,7 @@ class ContractorFinancialInfo(models.Model):
verbose_name = 'Финансовая информация'
verbose_name_plural = 'Финансовая информация'
class ContractorResume(models.Model):
resume_file = models.FileField(upload_to='users/resume/files/')
text = models.TextField()

@ -137,9 +137,15 @@
<div class="buttonGP disTab">
<div class="btn-group valProject valProject2" role="group" aria-label="...">
<button type="button" class="btn btn-default">Все</button>
<button type="button" class="btn btn-default">Группы</button>
<button type="button" class="btn btn-default">Исполнители</button>
{% for val, text in form.party_types.field.choices %}
<button
type="submit"
name="{{ form.party_types.html_name }}"
value="{{ val }}"
class="btn btn-default">
{{ text }}
</button>
{% endfor %}
</div>
<div class="polsF1 disTab polsSearch">
<div class="col-lg-3">
@ -155,154 +161,158 @@
{% for contractor in contractors %}
<div class="executorBlock clearfix">
<div class="col-lg-4">
<a href="#" class="aLinkExe"><div class="imgExecutor">
<img src="img/profile.jpg" alt="execitor-image">
</div></a>
<p class="nameExecutor">
<a href="#">{{ contractor.get_full_name }} [{{ contractor.username }}]</a>
</p>
<p class="navv2">На сайте 8 лет и 3 месяца</p>
<div class="statusUser">Свободен</div>
</div>
<div class="col-lg-2">
<ul class="listExecutor">
<li>
<a href="javascript:void(0)">
смотреть профиль
</a>
</li>
<li>
<a href="javascript:void(0)">
предложить проект
</a>
</li>
<li>
<a href="javascript:void(0)">
написать сообщение
</a>
</li>
</ul>
</div>
<div class="col-lg-3">
<div class="dashedCol4 dashedCol44">
<p class="specUser">
Специализации:
</p>
<div class="insetSpec">
<span>Интерьеры</span>
<span>2-й</span>
</div>
<div class="insetSpec">
<span>Визуализация/3D</span>
<span>45-й</span>
</div>
<div class="insetSpec">
<span>Экстерьеры</span>
<span>10-й</span>
</div>
<div class="showSpec">
<div class="insetSpec">
<span>Архитектура</span>
<span>3-й</span>
</div>
<div class="insetSpec">
<span>3D Моделирование</span>
<span>100-й</span>
</div>
</div>
<button class="showPress">
</button>
</div>
</div>
<div class="col-lg-3 retts">
<ul class="rettList restList2">
<li>Рейтинг: <span> 1245</span></li>
<li>Безопасные сделки: <span> 5</span></li>
<li>
<a href="javascript:void(0)">Отзывы:
<span> + 385</span>
<small> 0</small>
<mark> - 0</mark>
</a>
</li>
</ul>
<div class="sroUser sroExecutor">
<div class="iconSRO"></div>
<p>Есть допуск СРО</p>
</div>
</div>
{% if TEMPLATE_DEBUG %}
<div class="col-lg-12">
<pre><!--
--><b>Specializations:</b> {{ contractor.contractor_specializations.all }}<br><!--
--><br><!--
--><b>Location:</b> {{ contractor.location }}<br><!--
--><br><!--
--><b>Build. classif-s:</b> {% for o in contractor.orders.all %}{{ o.project.realty.building_classification }}, {% endfor %}<br><!--
--><br><!--
--><b>Constr. types:</b> {% for o in contractor.orders.all %}{{ o.project.realty.construction_type }}, {% endfor %}<br><!--
--><br><!--
--><b>CRO:</b> {{ contractor.cro }}<br><!--
--><br><!--
--><b>Work types:</b> {% for o in contractor.orders.all %}{{ o.project.work_type }}, {% endfor %}<br><!--
--></pre>
</div>
{% endif %}
<div class="gallMini disTab">
<div class="col-lg-3">
<a href="#" class="linkInsetCol">
<div class="insetCol box-sizing disTab">
<div class="imgGal">
<div class="imgFigure"></div>
</div>
</div>
</a>
</div>
<div class="col-lg-3">
<a href="#" class="linkInsetCol">
<div class="insetCol box-sizing disTab">
<div class="imgGal">
<div class="imgFigure"></div>
</div>
</div>
</a>
</div>
<div class="col-lg-3">
<a href="#" class="linkInsetCol">
<div class="insetCol box-sizing disTab">
<div class="imgGal">
<div class="imgFigure"></div>
</div>
</div>
</a>
</div>
<div class="col-lg-3">
<a href="#" class="linkInsetCol">
<div class="insetCol box-sizing disTab">
<div class="imgGal">
<div class="imgFigure"></div>
</div>
</div>
</a>
</div>
</div>
</div>
{% endfor %}
{# {% for contractor in contractors %}#}
{# <div class="executorBlock clearfix">#}
{# <div class="col-lg-4">#}
{# <a href="#" class="aLinkExe"><div class="imgExecutor">#}
{# <img src="img/profile.jpg" alt="execitor-image">#}
{# </div></a>#}
{# <p class="nameExecutor">#}
{# <a href="#">{{ contractor.get_full_name }} [{{ contractor.username }}]</a>#}
{# </p>#}
{# <p class="navv2">На сайте 8 лет и 3 месяца</p>#}
{# <div class="statusUser">Свободен</div>#}
{# </div>#}
{# #}
{# #}
{# <div class="col-lg-2">#}
{# <ul class="listExecutor">#}
{# <li>#}
{# <a href="javascript:void(0)">#}
{# смотреть профиль#}
{# </a>#}
{# </li>#}
{# <li>#}
{# <a href="javascript:void(0)">#}
{# предложить проект#}
{# </a>#}
{# </li>#}
{# <li>#}
{# <a href="javascript:void(0)">#}
{# написать сообщение#}
{# </a>#}
{# </li>#}
{# </ul>#}
{# </div>#}
{# #}
{# #}
{# <div class="col-lg-3">#}
{# <div class="dashedCol4 dashedCol44">#}
{# <p class="specUser">#}
{# Специализации:#}
{# </p>#}
{# <div class="insetSpec">#}
{# <span>Интерьеры</span>#}
{# <span>2-й</span>#}
{# </div>#}
{# <div class="insetSpec">#}
{# <span>Визуализация/3D</span>#}
{# <span>45-й</span>#}
{# </div>#}
{# <div class="insetSpec">#}
{# <span>Экстерьеры</span>#}
{# <span>10-й</span>#}
{# </div>#}
{# <div class="showSpec">#}
{# <div class="insetSpec">#}
{# <span>Архитектура</span>#}
{# <span>3-й</span>#}
{# </div>#}
{# <div class="insetSpec">#}
{# <span>3D Моделирование</span>#}
{# <span>100-й</span>#}
{# </div>#}
{# </div>#}
{# <button class="showPress">#}
{# #}
{# </button>#}
{# </div>#}
{# </div>#}
{# #}
{# #}
{# <div class="col-lg-3 retts">#}
{# <ul class="rettList restList2">#}
{# <li>Рейтинг: <span> 1245</span></li>#}
{# <li>Безопасные сделки: <span> 5</span></li>#}
{# <li>#}
{# <a href="javascript:void(0)">Отзывы: #}
{# <span> + 385</span>#}
{# <small> 0</small>#}
{# <mark> - 0</mark>#}
{# </a>#}
{# </li>#}
{# </ul>#}
{# <div class="sroUser sroExecutor">#}
{# <div class="iconSRO"></div>#}
{# <p>Есть допуск СРО</p>#}
{# </div>#}
{# </div>#}
{# #}
{# #}
{# {% if TEMPLATE_DEBUG %}#}
{# <div class="col-lg-12">#}
{# <pre><!--#}
{# --><b>Specializations:</b> {{ contractor.contractor_specializations.all }}<br><!--#}
{# --><br><!--#}
{# --><b>Location:</b> {{ contractor.location }}<br><!--#}
{# --><br><!--#}
{# --><b>Build. classif-s:</b> {% for o in contractor.orders.all %}{{ o.project.realty.building_classification }}, {% endfor %}<br><!--#}
{# --><br><!--#}
{# --><b>Constr. types:</b> {% for o in contractor.orders.all %}{{ o.project.realty.construction_type }}, {% endfor %}<br><!--#}
{# --><br><!--#}
{# --><b>CRO:</b> {{ contractor.cro }}<br><!--#}
{# --><br><!--#}
{# --><b>Work types:</b> {% for o in contractor.orders.all %}{{ o.project.work_type }}, {% endfor %}<br><!--#}
{# --></pre>#}
{# </div>#}
{# {% endif %}#}
{# #}
{# #}
{# <div class="gallMini disTab">#}
{# <div class="col-lg-3">#}
{# <a href="#" class="linkInsetCol">#}
{# <div class="insetCol box-sizing disTab">#}
{# <div class="imgGal">#}
{# <div class="imgFigure"></div>#}
{# </div>#}
{# </div>#}
{# </a>#}
{# </div>#}
{# <div class="col-lg-3">#}
{# <a href="#" class="linkInsetCol">#}
{# <div class="insetCol box-sizing disTab">#}
{# <div class="imgGal">#}
{# <div class="imgFigure"></div>#}
{# </div>#}
{# </div>#}
{# </a>#}
{# </div>#}
{# <div class="col-lg-3">#}
{# <a href="#" class="linkInsetCol">#}
{# <div class="insetCol box-sizing disTab">#}
{# <div class="imgGal">#}
{# <div class="imgFigure"></div>#}
{# </div>#}
{# </div>#}
{# </a>#}
{# </div>#}
{# <div class="col-lg-3">#}
{# <a href="#" class="linkInsetCol">#}
{# <div class="insetCol box-sizing disTab">#}
{# <div class="imgGal">#}
{# <div class="imgFigure"></div>#}
{# </div>#}
{# </div>#}
{# </a>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# {% endfor %}#}
{% for obj in coll %}
{# Get the type of an object, like `if type(obj) == Team: ...`#}
<div>{{ obj }}</div>
{% endfor %}
<div class="col-lg-12 pagin">

@ -8,11 +8,13 @@ from django.http import HttpResponse
from django.shortcuts import render, get_object_or_404, redirect
from django.views.generic import ListView, DetailView, View, UpdateView, CreateView
from pprint import pprint, pformat
import itertools
import natsort
import pydash as _; _.map = _.map_; _.filter = _.filter_
from .forms import UserEditForm, ContractorFilterForm, ContractorFinancicalInfoForm
from .mixins import CheckForUserMixin
from .models import User, ContractorFinancialInfo
from .models import User, Team, ContractorFinancialInfo
from archilance.mixins import BaseMixin
from common.utils import get_or_none
from projects.forms import PortfolioForm
@ -38,8 +40,7 @@ class ContractorFilterView(BaseMixin, View):
def get(self, request, *args, **kwargs):
form = self.form_class(request.GET, request=request)
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
contractors = User.contractor_objects
contractors = teams = None
if form.is_valid():
cro = form.cleaned_data.get('cro')
@ -48,56 +49,53 @@ class ContractorFilterView(BaseMixin, View):
work_type = form.cleaned_data.get('work_type')
build_classif = form.cleaned_data.get('building_classification')
constr_type = form.cleaned_data.get('construction_type')
party_types = form.cleaned_data.get('party_types')
contractors = contractors.filter(cro=cro)
if specialization:
contractors = contractors.filter(
# specialization__lft__gte=specialization.lft,
# specialization__rght__lte=specialization.rght,
contractor_specializations=specialization, # TODO: Honor the hierarchical data structure
)
if location:
contractors = contractors.filter(
location__lft__gte=location.lft,
location__rght__lte=location.rght,
)
get_contractors = get_teams = None
if work_type:
contractors = contractors.filter(orders__project__work_type=work_type).distinct() # TODO: OK?
if not party_types:
get_contractors = get_teams = True
elif party_types == 'contractors':
get_contractors = True
elif party_types == 'teams':
get_teams = True
if build_classif:
contractors = contractors.filter(orders__project__realty__building_classification=build_classif)
if constr_type:
contractors = contractors.filter(orders__project__realty__construction_type=constr_type)
# import code; code.interact(local=dict(globals(), **locals()))
if get_contractors:
contractors = User.contractor_objects.filter(cro=cro)
if specialization:
contractors = contractors.filter(
# specialization__lft__gte=specialization.lft,
# specialization__rght__lte=specialization.rght,
contractor_specializations=specialization, # TODO: Honor the hierarchical data structure
)
if location:
contractors = contractors.filter(
location__lft__gte=location.lft,
location__rght__lte=location.rght,
)
if work_type:
contractors = contractors.filter(orders__project__work_type=work_type).distinct() # TODO: OK?
if build_classif:
contractors = contractors.filter(orders__project__realty__building_classification=build_classif)
if constr_type:
contractors = contractors.filter(orders__project__realty__construction_type=constr_type)
# contr_count = contractors.count()
# display_msg = 'Найдено %s исполнителей' % contr_count if contr_count > 0 else 'Ничего не найдено'
# order_by = form.cleaned_data.get('order_by')
# last_order_by = form.cleaned_data.get('last_order_by')
# reverse_order = form.cleaned_data.get('reverse_order')
#
# if order_by:
# if order_by == last_order_by:
# reverse_order = not reverse_order
# else:
# reverse_order = False
#
# projects = projects.order_by('-%s' % order_by if reverse_order else order_by)
# last_order_by = order_by
# elif last_order_by:
# projects = projects.order_by('-%s' % last_order_by if reverse_order else last_order_by)
#
# context.update({
# 'last_order_by': last_order_by,
# 'reverse_order': reverse_order,
# })
if get_teams:
teams = Team.objects.all()
# team_count = teams.count()
# display_msg = 'Найдено %s команд' % team_count if team_count > 0 else 'Ничего не найдено'
contr_count = contractors.count()
display_msg = 'Найдено %s исполнителей' % contr_count if contr_count > 0 else 'Ничего не найдено'
display_msg = 'Результаты поиска'
else:
display_msg = 'Пожалуйста, введите корректные данные'
@ -107,22 +105,24 @@ class ContractorFilterView(BaseMixin, View):
'<pre>{form}</pre>'
).format(form=pformat(form.errors)))
coll = tuple(itertools.chain(contractors, teams))
coll = natsort.natsorted(coll, key=lambda obj: getattr(obj, 'username', None) or getattr(obj, 'name'))
paginator = Paginator(contractors.all(), settings.PAGE_SIZE)
paginator = Paginator(coll, settings.PAGE_SIZE)
page = request.GET.get('page')
try:
contractors = paginator.page(page)
coll = paginator.page(page)
except PageNotAnInteger:
contractors = paginator.page(1)
coll = paginator.page(1)
except EmptyPage:
contractors = paginator.page(paginator.num_pages)
coll = paginator.page(paginator.num_pages)
context.update({
'form': form,
'contractors': contractors,
'coll': coll,
'is_paginated': True,
'page_obj': contractors,
'page_obj': coll,
'display_msg': display_msg,
})

Loading…
Cancel
Save