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 SHELL_PLUS_POST_IMPORTS = ( # Extra auto imports
'natsort',
('archilance', 'util'), ('archilance', 'util'),
('pprint', ('pprint', 'pformat')), ('pprint', ('pprint', 'pformat')),
) )

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

@ -47,7 +47,13 @@ class ContractorFilterForm(forms.Form):
# ('created', 'дате размещения'), # ('created', 'дате размещения'),
# ('views', 'просмотрам'), # ('views', 'просмотрам'),
# ) # )
#
PARTY_TYPES = (
('', 'Все'),
('teams', 'Группы'),
('contractors', 'Исполнители'),
)
# order_by = forms.ChoiceField(required=False, choices=PROJECT_ORDER_CHOICES) # order_by = forms.ChoiceField(required=False, choices=PROJECT_ORDER_CHOICES)
# last_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) # reverse_order = forms.BooleanField(required=False)
@ -84,6 +90,11 @@ class ContractorFilterForm(forms.Form):
cro = forms.BooleanField(required=False) cro = forms.BooleanField(required=False)
party_types = forms.ChoiceField(
choices=PARTY_TYPES,
required=False,
)
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)

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

@ -137,9 +137,15 @@
<div class="buttonGP disTab"> <div class="buttonGP disTab">
<div class="btn-group valProject valProject2" role="group" aria-label="..."> <div class="btn-group valProject valProject2" role="group" aria-label="...">
<button type="button" class="btn btn-default">Все</button> {% for val, text in form.party_types.field.choices %}
<button type="button" class="btn btn-default">Группы</button> <button
<button type="button" class="btn btn-default">Исполнители</button> type="submit"
name="{{ form.party_types.html_name }}"
value="{{ val }}"
class="btn btn-default">
{{ text }}
</button>
{% endfor %}
</div> </div>
<div class="polsF1 disTab polsSearch"> <div class="polsF1 disTab polsSearch">
<div class="col-lg-3"> <div class="col-lg-3">
@ -155,154 +161,158 @@
{% for contractor in contractors %} {# {% for contractor in contractors %}#}
<div class="executorBlock clearfix"> {# <div class="executorBlock clearfix">#}
<div class="col-lg-4"> {# <div class="col-lg-4">#}
<a href="#" class="aLinkExe"><div class="imgExecutor"> {# <a href="#" class="aLinkExe"><div class="imgExecutor">#}
<img src="img/profile.jpg" alt="execitor-image"> {# <img src="img/profile.jpg" alt="execitor-image">#}
</div></a> {# </div></a>#}
<p class="nameExecutor"> {# <p class="nameExecutor">#}
<a href="#">{{ contractor.get_full_name }} [{{ contractor.username }}]</a> {# <a href="#">{{ contractor.get_full_name }} [{{ contractor.username }}]</a>#}
</p> {# </p>#}
<p class="navv2">На сайте 8 лет и 3 месяца</p> {# <p class="navv2">На сайте 8 лет и 3 месяца</p>#}
<div class="statusUser">Свободен</div> {# <div class="statusUser">Свободен</div>#}
</div> {# </div>#}
{# #}
{# #}
<div class="col-lg-2"> {# <div class="col-lg-2">#}
<ul class="listExecutor"> {# <ul class="listExecutor">#}
<li> {# <li>#}
<a href="javascript:void(0)"> {# <a href="javascript:void(0)">#}
смотреть профиль {# смотреть профиль#}
</a> {# </a>#}
</li> {# </li>#}
<li> {# <li>#}
<a href="javascript:void(0)"> {# <a href="javascript:void(0)">#}
предложить проект {# предложить проект#}
</a> {# </a>#}
</li> {# </li>#}
<li> {# <li>#}
<a href="javascript:void(0)"> {# <a href="javascript:void(0)">#}
написать сообщение {# написать сообщение#}
</a> {# </a>#}
</li> {# </li>#}
</ul> {# </ul>#}
</div> {# </div>#}
{# #}
{# #}
<div class="col-lg-3"> {# <div class="col-lg-3">#}
<div class="dashedCol4 dashedCol44"> {# <div class="dashedCol4 dashedCol44">#}
<p class="specUser"> {# <p class="specUser">#}
Специализации: {# Специализации:#}
</p> {# </p>#}
<div class="insetSpec"> {# <div class="insetSpec">#}
<span>Интерьеры</span> {# <span>Интерьеры</span>#}
<span>2-й</span> {# <span>2-й</span>#}
</div> {# </div>#}
<div class="insetSpec"> {# <div class="insetSpec">#}
<span>Визуализация/3D</span> {# <span>Визуализация/3D</span>#}
<span>45-й</span> {# <span>45-й</span>#}
</div> {# </div>#}
<div class="insetSpec"> {# <div class="insetSpec">#}
<span>Экстерьеры</span> {# <span>Экстерьеры</span>#}
<span>10-й</span> {# <span>10-й</span>#}
</div> {# </div>#}
<div class="showSpec"> {# <div class="showSpec">#}
<div class="insetSpec"> {# <div class="insetSpec">#}
<span>Архитектура</span> {# <span>Архитектура</span>#}
<span>3-й</span> {# <span>3-й</span>#}
</div> {# </div>#}
<div class="insetSpec"> {# <div class="insetSpec">#}
<span>3D Моделирование</span> {# <span>3D Моделирование</span>#}
<span>100-й</span> {# <span>100-й</span>#}
</div> {# </div>#}
</div> {# </div>#}
<button class="showPress"> {# <button class="showPress">#}
{# #}
</button> {# </button>#}
</div> {# </div>#}
</div> {# </div>#}
{# #}
{# #}
<div class="col-lg-3 retts"> {# <div class="col-lg-3 retts">#}
<ul class="rettList restList2"> {# <ul class="rettList restList2">#}
<li>Рейтинг: <span> 1245</span></li> {# <li>Рейтинг: <span> 1245</span></li>#}
<li>Безопасные сделки: <span> 5</span></li> {# <li>Безопасные сделки: <span> 5</span></li>#}
<li> {# <li>#}
<a href="javascript:void(0)">Отзывы: {# <a href="javascript:void(0)">Отзывы: #}
<span> + 385</span> {# <span> + 385</span>#}
<small> 0</small> {# <small> 0</small>#}
<mark> - 0</mark> {# <mark> - 0</mark>#}
</a> {# </a>#}
</li> {# </li>#}
</ul> {# </ul>#}
<div class="sroUser sroExecutor"> {# <div class="sroUser sroExecutor">#}
<div class="iconSRO"></div> {# <div class="iconSRO"></div>#}
<p>Есть допуск СРО</p> {# <p>Есть допуск СРО</p>#}
</div> {# </div>#}
</div> {# </div>#}
{# #}
{# #}
{% if TEMPLATE_DEBUG %} {# {% if TEMPLATE_DEBUG %}#}
<div class="col-lg-12"> {# <div class="col-lg-12">#}
<pre><!-- {# <pre><!--#}
--><b>Specializations:</b> {{ contractor.contractor_specializations.all }}<br><!-- {# --><b>Specializations:</b> {{ contractor.contractor_specializations.all }}<br><!--#}
--><br><!-- {# --><br><!--#}
--><b>Location:</b> {{ contractor.location }}<br><!-- {# --><b>Location:</b> {{ contractor.location }}<br><!--#}
--><br><!-- {# --><br><!--#}
--><b>Build. classif-s:</b> {% for o in contractor.orders.all %}{{ o.project.realty.building_classification }}, {% endfor %}<br><!-- {# --><b>Build. classif-s:</b> {% for o in contractor.orders.all %}{{ o.project.realty.building_classification }}, {% endfor %}<br><!--#}
--><br><!-- {# --><br><!--#}
--><b>Constr. types:</b> {% for o in contractor.orders.all %}{{ o.project.realty.construction_type }}, {% endfor %}<br><!-- {# --><b>Constr. types:</b> {% for o in contractor.orders.all %}{{ o.project.realty.construction_type }}, {% endfor %}<br><!--#}
--><br><!-- {# --><br><!--#}
--><b>CRO:</b> {{ contractor.cro }}<br><!-- {# --><b>CRO:</b> {{ contractor.cro }}<br><!--#}
--><br><!-- {# --><br><!--#}
--><b>Work types:</b> {% for o in contractor.orders.all %}{{ o.project.work_type }}, {% endfor %}<br><!-- {# --><b>Work types:</b> {% for o in contractor.orders.all %}{{ o.project.work_type }}, {% endfor %}<br><!--#}
--></pre> {# --></pre>#}
</div> {# </div>#}
{% endif %} {# {% endif %}#}
{# #}
{# #}
<div class="gallMini disTab"> {# <div class="gallMini disTab">#}
<div class="col-lg-3"> {# <div class="col-lg-3">#}
<a href="#" class="linkInsetCol"> {# <a href="#" class="linkInsetCol">#}
<div class="insetCol box-sizing disTab"> {# <div class="insetCol box-sizing disTab">#}
<div class="imgGal"> {# <div class="imgGal">#}
<div class="imgFigure"></div> {# <div class="imgFigure"></div>#}
</div> {# </div>#}
</div> {# </div>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="col-lg-3"> {# <div class="col-lg-3">#}
<a href="#" class="linkInsetCol"> {# <a href="#" class="linkInsetCol">#}
<div class="insetCol box-sizing disTab"> {# <div class="insetCol box-sizing disTab">#}
<div class="imgGal"> {# <div class="imgGal">#}
<div class="imgFigure"></div> {# <div class="imgFigure"></div>#}
</div> {# </div>#}
</div> {# </div>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="col-lg-3"> {# <div class="col-lg-3">#}
<a href="#" class="linkInsetCol"> {# <a href="#" class="linkInsetCol">#}
<div class="insetCol box-sizing disTab"> {# <div class="insetCol box-sizing disTab">#}
<div class="imgGal"> {# <div class="imgGal">#}
<div class="imgFigure"></div> {# <div class="imgFigure"></div>#}
</div> {# </div>#}
</div> {# </div>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="col-lg-3"> {# <div class="col-lg-3">#}
<a href="#" class="linkInsetCol"> {# <a href="#" class="linkInsetCol">#}
<div class="insetCol box-sizing disTab"> {# <div class="insetCol box-sizing disTab">#}
<div class="imgGal"> {# <div class="imgGal">#}
<div class="imgFigure"></div> {# <div class="imgFigure"></div>#}
</div> {# </div>#}
</div> {# </div>#}
</a> {# </a>#}
</div> {# </div>#}
</div> {# </div>#}
</div> {# </div>#}
{% endfor %} {# {% 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"> <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.shortcuts import render, get_object_or_404, redirect
from django.views.generic import ListView, DetailView, View, UpdateView, CreateView from django.views.generic import ListView, DetailView, View, UpdateView, CreateView
from pprint import pprint, pformat from pprint import pprint, pformat
import itertools
import natsort
import pydash as _; _.map = _.map_; _.filter = _.filter_ import pydash as _; _.map = _.map_; _.filter = _.filter_
from .forms import UserEditForm, ContractorFilterForm, ContractorFinancicalInfoForm from .forms import UserEditForm, ContractorFilterForm, ContractorFinancicalInfoForm
from .mixins import CheckForUserMixin from .mixins import CheckForUserMixin
from .models import User, ContractorFinancialInfo from .models import User, Team, ContractorFinancialInfo
from archilance.mixins import BaseMixin from archilance.mixins import BaseMixin
from common.utils import get_or_none from common.utils import get_or_none
from projects.forms import PortfolioForm from projects.forms import PortfolioForm
@ -38,8 +40,7 @@ class ContractorFilterView(BaseMixin, View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
form = self.form_class(request.GET, request=request) form = self.form_class(request.GET, request=request)
context = self.get_context_data(**_.merge({}, request.GET, kwargs)) context = self.get_context_data(**_.merge({}, request.GET, kwargs))
contractors = teams = None
contractors = User.contractor_objects
if form.is_valid(): if form.is_valid():
cro = form.cleaned_data.get('cro') cro = form.cleaned_data.get('cro')
@ -48,56 +49,53 @@ class ContractorFilterView(BaseMixin, View):
work_type = form.cleaned_data.get('work_type') work_type = form.cleaned_data.get('work_type')
build_classif = form.cleaned_data.get('building_classification') build_classif = form.cleaned_data.get('building_classification')
constr_type = form.cleaned_data.get('construction_type') constr_type = form.cleaned_data.get('construction_type')
party_types = form.cleaned_data.get('party_types')
contractors = contractors.filter(cro=cro) get_contractors = get_teams = None
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: if not party_types:
contractors = contractors.filter(orders__project__work_type=work_type).distinct() # TODO: OK? get_contractors = get_teams = True
elif party_types == 'contractors':
get_contractors = True
elif party_types == 'teams':
get_teams = True
if build_classif: if get_contractors:
contractors = contractors.filter(orders__project__realty__building_classification=build_classif) contractors = User.contractor_objects.filter(cro=cro)
if constr_type: if specialization:
contractors = contractors.filter(orders__project__realty__construction_type=constr_type) contractors = contractors.filter(
# specialization__lft__gte=specialization.lft,
# import code; code.interact(local=dict(globals(), **locals())) # 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') if get_teams:
# last_order_by = form.cleaned_data.get('last_order_by') teams = Team.objects.all()
# reverse_order = form.cleaned_data.get('reverse_order')
# # team_count = teams.count()
# if order_by: # display_msg = 'Найдено %s команд' % team_count if team_count > 0 else 'Ничего не найдено'
# 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,
# })
contr_count = contractors.count() display_msg = 'Результаты поиска'
display_msg = 'Найдено %s исполнителей' % contr_count if contr_count > 0 else 'Ничего не найдено'
else: else:
display_msg = 'Пожалуйста, введите корректные данные' display_msg = 'Пожалуйста, введите корректные данные'
@ -107,22 +105,24 @@ class ContractorFilterView(BaseMixin, View):
'<pre>{form}</pre>' '<pre>{form}</pre>'
).format(form=pformat(form.errors))) ).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') page = request.GET.get('page')
try: try:
contractors = paginator.page(page) coll = paginator.page(page)
except PageNotAnInteger: except PageNotAnInteger:
contractors = paginator.page(1) coll = paginator.page(1)
except EmptyPage: except EmptyPage:
contractors = paginator.page(paginator.num_pages) coll = paginator.page(paginator.num_pages)
context.update({ context.update({
'form': form, 'form': form,
'contractors': contractors, 'coll': coll,
'is_paginated': True, 'is_paginated': True,
'page_obj': contractors, 'page_obj': coll,
'display_msg': display_msg, 'display_msg': display_msg,
}) })

Loading…
Cancel
Save