#ARC-22 REstore migrations

remotes/origin/setup
Mukhtar 10 years ago
commit 78938cd9e9
  1. 19
      README.md
  2. 6
      api/views.py
  3. 20
      archilance/management/commands/_template.py
  4. 18
      archilance/management/commands/generate_build_classifs.py
  5. 18
      archilance/management/commands/generate_constr_types.py
  6. 71
      archilance/management/commands/generate_portfolios.py
  7. 7
      archilance/management/commands/generate_projects.py
  8. 5
      archilance/management/commands/generate_realties.py
  9. 41
      archilance/management/commands/generate_reviews.py
  10. 8
      archilance/management/commands/generate_specializations.py
  11. 46
      archilance/management/commands/generate_teams.py
  12. 6
      archilance/management/commands/generate_users.py
  13. 28
      archilance/management/commands/tmp.py
  14. 1
      archilance/settings/base.py
  15. 1
      assets/index.js
  16. 42
      chat/migrations_/0001_initial.py
  17. 24
      chat/migrations_/0002_notes_order.py
  18. 46
      chat/migrations_/0003_auto_20160721_1808.py
  19. 0
      chat/migrations_/__init__.py
  20. 62
      common/migrations_/0001_initial.py
  21. 0
      common/migrations_/__init__.py
  22. 50
      common/migrations_mukhtar/0001_initial.py
  23. 5
      common/templatetags/common_tags.py
  24. 18
      projects/forms.py
  25. 114
      projects/migrations/0002_auto_20160721_1808.py
  26. 176
      projects/migrations_/0001_initial.py
  27. 114
      projects/migrations_/0002_auto_20160721_1808.py
  28. 0
      projects/migrations_/__init__.py
  29. 131
      projects/migrations_mukhtar/0001_initial.py
  30. 46
      projects/models.py
  31. 53
      projects/templates/project_filter.html
  32. 22
      projects/views.py
  33. 5
      requirements/base.txt
  34. 46
      reviews/migrations/0002_auto_20160721_1808.py
  35. 46
      reviews/migrations_/0002_auto_20160721_1808.py
  36. 41
      reviews/migrations_/0003_auto_20160721_2021.py
  37. 0
      reviews/migrations_/__init__.py
  38. 14
      reviews/migrations_mukhtar/0001_initial.py
  39. 22
      reviews/models.py
  40. 34
      specializations/migrations_/0001_initial.py
  41. 0
      specializations/migrations_/__init__.py
  42. 5
      specializations/migrations_mukhtar/0001_initial.py
  43. 5
      specializations/views.py
  44. 8
      templates/home.html
  45. 250
      templates/partials/header.html
  46. 50
      templates/partials/pagination.html
  47. 19
      templates/trash/contractor-filter.html
  48. 80
      users/forms.py
  49. 149
      users/migrations_/0001_initial.py
  50. 0
      users/migrations_/__init__.py
  51. 110
      users/migrations_mukhtar/0001_initial.py
  52. 64
      users/models.py
  53. 446
      users/templates/contractor_filter.html
  54. 7
      users/templates/contractor_list.html
  55. 2
      users/templates/contractor_profile.html
  56. 2
      users/templates/customer_profile_reviews.html
  57. 16
      users/urls.py
  58. 211
      users/views.py
  59. 4
      work_sell/forms.py
  60. 69
      work_sell/migrations_/0001_initial.py
  61. 0
      work_sell/migrations_/__init__.py
  62. 50
      work_sell/migrations_mukhtar/0001_initial.py
  63. 16
      work_sell/models.py
  64. 296
      work_sell/templates/worksells_list.html

@ -21,3 +21,22 @@ python manage.py runserver
``` ```
python manage.py shell_plus --use-pythonrc python manage.py shell_plus --use-pythonrc
``` ```
----------------------------------------
Data generation order:
1. Superuser
2. Specializations
3. Locations
4. Perm. groups
5. Build. classif-s
6. Constr. types
7. Users
8. Teams
9. Realties
10. Projects
11. Portfolios
12. Reviews
----------------------------------------

@ -55,7 +55,8 @@ class RealtyViewSet(ModelViewSet):
class SpecializationViewSet(ModelViewSet): class SpecializationViewSet(ModelViewSet):
queryset = Specialization.objects.root_nodes()[0].get_descendants() # queryset = Specialization.objects.root_nodes()[0].get_descendants()
queryset = Specialization.objects # TODO: Tmp
serializer_class = SpecializationSerializer serializer_class = SpecializationSerializer
filter_class = SpecializationFilterSet filter_class = SpecializationFilterSet
@ -67,6 +68,7 @@ class UserViewSet(ModelViewSet):
class LocationViewSet(ModelViewSet): class LocationViewSet(ModelViewSet):
queryset = Location.objects.root_nodes()[0].get_descendants() # queryset = Location.objects.root_nodes()[0].get_descendants()
queryset = Location.objects # TODO: Tmp
serializer_class = LocationSerializer serializer_class = LocationSerializer
filter_class = LocationFilterSet filter_class = LocationFilterSet

@ -0,0 +1,20 @@
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 something...')
print('---------------------------------------')
pass

@ -0,0 +1,18 @@
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 projects.models import BuildingClassfication
class Command(BaseCommand):
def handle(self, *args, **options):
print('---------------------------------------')
print('Generating building classifications...')
print('---------------------------------------')
_.times(lambda i: BuildingClassfication.objects.create(name='Build. classif. %s' % i), 100)

@ -0,0 +1,18 @@
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 projects.models import ConstructionType
class Command(BaseCommand):
def handle(self, *args, **options):
print('---------------------------------------')
print('Generating construction types...')
print('---------------------------------------')
_.times(lambda i: ConstructionType.objects.create(name='Constr. type %s' % i), 100)

@ -0,0 +1,71 @@
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 projects.models import Portfolio, PortfolioPhoto, CURRENCIES, TERMS, BuildingClassfication , ConstructionType
from specializations.models import Specialization
from users.models import User, Team, GENDERS
class Command(BaseCommand):
def handle(self, *args, **options):
print('---------------------------------------')
print('Generating portfolios...')
print('---------------------------------------')
# ('photos', 'Relation? True', 'Null? True', '(relation)', 'Hidden? False'),
# ('budget', 'Relation? False', 'Null? True', 'Blank? True', 'Hidden? False'),
# ('building_classification', 'Relation? True', 'Null? True', '(relation)', 'Hidden? False'),
# ('construction_type', 'Relation? True', 'Null? True', '(relation)', 'Hidden? False'),
# ('currency', 'Relation? False', 'Null? True', 'Blank? True', 'Hidden? False'),
# ('description', 'Relation? False', 'Null? False', 'Blank? False', 'Hidden? False'),
# ('location', 'Relation? True', 'Null? True', '(relation)', 'Hidden? False'),
# ('name', 'Relation? False', 'Null? False', 'Blank? False', 'Hidden? False'),
# ('specialization', 'Relation? True', 'Null? True', '(relation)', 'Hidden? False'),
# ('team', 'Relation? True', 'Null? True', '(relation)', 'Hidden? False'),
# ('term', 'Relation? False', 'Null? True', 'Blank? True', 'Hidden? False'),
# ('term_type', 'Relation? False', 'Null? True', 'Blank? True', 'Hidden? False'),
# ('user', 'Relation? True', 'Null? True', '(relation)', 'Hidden? False'),
# ('worksell', 'Relation? False', 'Null? False', 'Blank? True', 'Hidden? False'),
def create_portfolio(i):
portf = Portfolio(
name='Portforlio %s' % i,
description="Portforlio %s's description" % i,
budget=util.random_amount(),
currency=_.sample(CURRENCIES)[0],
term=_.random(0, 20),
term_type=_.sample(TERMS)[0],
worksell=_.sample((True, False)),
)
portf.save()
if _.sample((True, False)):
portf.user = User.contractor_objects.order_by('?').first()
else:
portf.team = Team.objects.order_by('?').first()
portf.building_classification = BuildingClassfication.objects.order_by('?').first()
portf.construction_type = ConstructionType.objects.order_by('?').first()
portf.location = Location.objects.root_nodes()[0].get_descendants().order_by('?').first()
portf.specialization = Specialization.objects.root_nodes()[0].get_descendants().order_by('?').first()
pic_names = _.split('a.png b.png c.jpg d.png e.jpg f.png g.png h.jpg i.png j.png k.jpg l.png m.png n.png o.png p.png q.jpg', ' ')
_.times(
lambda i_: portf.photos.create(img='_sample_files/%s' % util.take_one_random(pic_names)),
_.random(1, 15),
)
portf.save()
return portf
_.times(create_portfolio, 1000)

@ -74,7 +74,12 @@ class Command(BaseCommand):
project.save() project.save()
Order.objects.create(project=project) Order.objects.create(
project=project,
contractor=_.sample((None, User.contractor_objects.order_by('?').first())),
secure=_.sample((True, False)),
status=_.sample((True, False)),
)
return project return project

@ -33,11 +33,6 @@ class Command(BaseCommand):
# ('name', 'Relation? False', 'Null? False', 'Blank? False', 'Hidden? False'), # ('name', 'Relation? False', 'Null? False', 'Blank? False', 'Hidden? False'),
_.times(lambda i: BuildingClassfication.objects.create(name='Build. classif. %s' % i), 50)
_.times(lambda i: ConstructionType.objects.create(name='Constr. type %s' % i), 50)
def create_realty(i): def create_realty(i):
realty = Realty(name='Realty %s' % i) realty = Realty(name='Realty %s' % i)

@ -0,0 +1,41 @@
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 projects.models import Project, Portfolio
from specializations.models import Specialization
from users.models import User, GENDERS, Team
from reviews.models import Review
class Command(BaseCommand):
def handle(self, *args, **options):
print('---------------------------------------')
print('Generating reviews...')
print('---------------------------------------')
def create_review(i):
review = Review()
review.project = Project.objects.order_by('?').first()
review.stars = _.random(1, 5)
review.text = 'This is a review %s text' % i
review.is_secured = _.sample((True, False))
review.save()
if _.sample((True, False)):
review.from_contractor = User.contractor_objects.order_by('?').first()
review.target_customer = User.customer_objects.order_by('?').first()
else:
review.from_customer = User.customer_objects.order_by('?').first()
review.target_contractor = User.contractor_objects.order_by('?').first()
review.save()
return review
_.times(create_review, 300)

@ -18,10 +18,10 @@ class Command(BaseCommand):
stages = ('A','B','C','D') stages = ('A','B','C','D')
for s1 in stages: for s1 in stages:
x = Specialization.objects.create(name='Стадия %s' % s1, parent=_root) x = Specialization.objects.create(name='Специализация %s' % s1, parent=_root)
for s2 in stages: for s2 in stages:
y = Specialization.objects.create(name='Стадия %s-%s' % (s1,s2), parent=x) y = Specialization.objects.create(name='Специализация %s-%s' % (s1,s2), parent=x)
for s3 in stages: for s3 in stages:
z = Specialization.objects.create(name='Стадия %s-%s-%s' % (s1,s2,s3), parent=y) z = Specialization.objects.create(name='Специализация %s-%s-%s' % (s1,s2,s3), parent=y)
for s4 in stages: for s4 in stages:
Specialization.objects.create(name='Стадия %s-%s-%s-%s' % (s1,s2,s3,s4), parent=z) Specialization.objects.create(name='Специализация %s-%s-%s-%s' % (s1,s2,s3,s4), parent=z)

@ -0,0 +1,46 @@
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 projects.models import Portfolio
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('---------------------------------------')
# ('name', 'Relation? False', 'Null? False', 'Blank? False', 'Hidden? False'),
# ('portfolios', 'Relation? True', 'Null? True', '(relation)', 'Hidden? False'),
# ('owner', 'Relation? True', 'Null? True', '(relation)', 'Hidden? False'),
# ('users', 'Relation? True', 'Null? False', '(relation)', 'Hidden? False'),
# ('specializations', 'Relation? True', 'Null? False', '(relation)', 'Hidden? False'),
contractors = list(User.contractor_objects.order_by('?'))
owners = util.take(contractors, len(contractors) // 2)
members = contractors
i = 0
for owner in owners:
team = Team(name='Team %s' % i)
team.save()
team.owner = owner
team.users = _.sample(members, _.random(1, 5))
team.specializations = Specialization.objects.root_nodes()[0].get_descendants().order_by('?')[:_.random(1, 5)]
team.portfolios = Portfolio.objects.order_by('?')[:_.random(1, 10)]
team.save()
i += 1

@ -6,6 +6,7 @@ import pydash as _; _.map = _.map_; _.filter = _.filter_
import random import random
from archilance import util from archilance import util
from common.models import Location
from specializations.models import Specialization from specializations.models import Specialization
from users.models import User, GENDERS from users.models import User, GENDERS
@ -85,7 +86,7 @@ class Command(BaseCommand):
contractor_status=_.sample(User.STATUSES)[0], contractor_status=_.sample(User.STATUSES)[0],
) )
users = _.times(create_user, 50) users = _.times(create_user, 500)
contractor_group = Group.objects.get(name='Исполнители') contractor_group = Group.objects.get(name='Исполнители')
@ -94,6 +95,7 @@ class Command(BaseCommand):
for user in users: for user in users:
user.set_password('123') user.set_password('123')
user.groups.add(customer_group if user.pk % 2 == 0 else contractor_group) user.groups.add(customer_group if user.pk % 2 == 0 else contractor_group)
user.contractor_specializations = Specialization.objects.order_by('?')[:_.random(1, 5)] user.contractor_specializations = Specialization.objects.root_nodes()[0].get_descendants().order_by('?')[:_.random(1, 5)]
user.location = Location.objects.root_nodes()[0].get_descendants().order_by('?').first()
user.save() user.save()

@ -0,0 +1,28 @@
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 projects.models import Project, Order, CURRENCIES, TERMS, Specialization, Realty
from users.models import User, Team
class Command(BaseCommand):
def handle(self, *args, **options):
# for user in User.objects.all():
# user.location = Location.objects.root_nodes()[0].get_descendants().order_by('?').first()
# user.cro = _.sample((True, False))
#
# user.save()
#------------------------------------------
for team in Team.objects.all():
# team.specializations = Specialization.objects.root_nodes()[0].get_descendants().order_by('?')[:_.random(1, 5)]
team.created = util.random_date()
team.save()

@ -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')),
) )

@ -242,6 +242,7 @@ function getSpecializationTree(specId) {
var specs = { var specs = {
specLevel1: null, specLevel2: null, specLevel3: null, specLevel4: null, specLevel1: null, specLevel2: null, specLevel3: null, specLevel4: null,
} }
if (specId === null) { if (specId === null) {
return $.when(specs) return $.when(specs)
} else { } else {

@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-21 15:08
from __future__ import unicode_literals
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Message',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('text', models.TextField()),
('created', models.DateTimeField(default=django.utils.timezone.now)),
('private_type', models.BooleanField(default=False)),
],
options={
'verbose_name': 'Сообщение',
'verbose_name_plural': 'Сообщения',
},
),
migrations.CreateModel(
name='Notes',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('text', models.TextField()),
('created', models.DateTimeField(default=django.utils.timezone.now)),
],
options={
'verbose_name': 'Заметка',
'verbose_name_plural': 'Заметки',
},
),
]

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-21 15:08
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('chat', '0001_initial'),
('projects', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='notes',
name='order',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='order_notes', to='projects.Order'),
),
]

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-21 15:08
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('projects', '0001_initial'),
('chat', '0002_notes_order'),
]
operations = [
migrations.AddField(
model_name='notes',
name='recipent',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='recipent_notes', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='notes',
name='sender',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sender_notes', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='message',
name='order',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='order_messages', to='projects.Order'),
),
migrations.AddField(
model_name='message',
name='recipent',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='recipent_messages', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='message',
name='sender',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sender_messages', to=settings.AUTH_USER_MODEL),
),
]

@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-21 15:08
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import django.db.models.manager
import mptt.fields
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Location',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)),
('type', models.CharField(choices=[('_root', 'Корень'), ('country', 'Страна'), ('region', 'Регион'), ('town', 'Город')], max_length=20)),
('lft', models.PositiveIntegerField(db_index=True, editable=False)),
('rght', models.PositiveIntegerField(db_index=True, editable=False)),
('tree_id', models.PositiveIntegerField(db_index=True, editable=False)),
('level', models.PositiveIntegerField(db_index=True, editable=False)),
('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='common.Location')),
],
options={
'verbose_name': 'Местоположение',
'verbose_name_plural': 'Местоположения',
},
managers=[
('_default_manager', django.db.models.manager.Manager()),
],
),
migrations.CreateModel(
name='MainPage',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('contractor_text', models.TextField()),
('customer_text', models.TextField()),
('video_code', models.TextField()),
],
options={
'verbose_name': 'Главная страница',
},
),
migrations.CreateModel(
name='Settings',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('time_notification', models.IntegerField(default=180)),
],
options={
'verbose_name': 'Настройки сайта',
'verbose_name_plural': 'Настройки сайта',
},
),
]

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-06-15 12:56 # Generated by Django 1.9.7 on 2016-07-21 15:08
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
@ -17,50 +17,46 @@ class Migration(migrations.Migration):
operations = [ operations = [
migrations.CreateModel( migrations.CreateModel(
name='City', name='Location',
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)), ('name', models.CharField(max_length=50)),
('type', models.CharField(choices=[('_root', 'Корень'), ('country', 'Страна'), ('region', 'Регион'), ('town', 'Город')], max_length=20)),
('lft', models.PositiveIntegerField(db_index=True, editable=False)),
('rght', models.PositiveIntegerField(db_index=True, editable=False)),
('tree_id', models.PositiveIntegerField(db_index=True, editable=False)),
('level', models.PositiveIntegerField(db_index=True, editable=False)),
('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='common.Location')),
], ],
options={ options={
'verbose_name_plural': 'Города', 'verbose_name': 'Местоположение',
'verbose_name': 'Город', 'verbose_name_plural': 'Местоположения',
}, },
managers=[
('_default_manager', django.db.models.manager.Manager()),
],
), ),
migrations.CreateModel( migrations.CreateModel(
name='Country', name='MainPage',
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)), ('contractor_text', models.TextField()),
('customer_text', models.TextField()),
('video_code', models.TextField()),
], ],
options={ options={
'verbose_name_plural': 'Страны', 'verbose_name': 'Главная страница',
'verbose_name': 'Страна',
}, },
), ),
migrations.CreateModel( migrations.CreateModel(
name='Location', name='Settings',
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)), ('time_notification', models.IntegerField(default=180)),
('type', models.CharField(blank=True, choices=[('country', 'Страна'), ('region', 'Регион'), ('town', 'Город')], max_length=20, null=True)),
('lft', models.PositiveIntegerField(db_index=True, editable=False)),
('rght', models.PositiveIntegerField(db_index=True, editable=False)),
('tree_id', models.PositiveIntegerField(db_index=True, editable=False)),
('level', models.PositiveIntegerField(db_index=True, editable=False)),
('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='common.Location')),
], ],
options={ options={
'verbose_name_plural': 'Местоположения', 'verbose_name': 'Настройки сайта',
'verbose_name': 'Местоположение', 'verbose_name_plural': 'Настройки сайта',
}, },
managers=[
('_default_manager', django.db.models.manager.Manager()),
],
),
migrations.AddField(
model_name='city',
name='country',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cities', to='common.Country'),
), ),
] ]

@ -30,6 +30,11 @@ def to_str(val):
return str(val) return str(val)
@register.filter('class_name')
def class_name(val):
return type(val).__name__
@register.filter @register.filter
def multiply(string, times): def multiply(string, times):
return string * times return string * times

@ -10,11 +10,6 @@ from common.models import Location
from users.models import User from users.models import User
# RealtyFormSet = inlineformset_factory(Project, Realty)
class ProjectFilterForm(forms.ModelForm): class ProjectFilterForm(forms.ModelForm):
PROJECT_ORDER_CHOICES = ( # "Упорядочить по"... PROJECT_ORDER_CHOICES = ( # "Упорядочить по"...
('name', 'названию'), ('name', 'названию'),
@ -51,7 +46,8 @@ class ProjectFilterForm(forms.ModelForm):
self.fields['specialization'].required = False self.fields['specialization'].required = False
self.fields['specialization'].queryset = Specialization.objects.root_nodes()[0].get_descendants() # self.fields['specialization'].queryset = Specialization.objects.root_nodes()[0].get_descendants()
self.fields['specialization'].queryset = Specialization.objects # TODO: Tmp
class ProjectFilterRealtyForm(forms.ModelForm): class ProjectFilterRealtyForm(forms.ModelForm):
@ -79,7 +75,8 @@ class ProjectFilterRealtyForm(forms.ModelForm):
self.fields['construction_type'].empty_label = '' self.fields['construction_type'].empty_label = ''
self.fields['construction_type'].required = False self.fields['construction_type'].required = False
self.fields['location'].queryset = Location.objects.root_nodes()[0].get_descendants() # self.fields['location'].queryset = Location.objects.root_nodes()[0].get_descendants()
self.fields['location'].queryset = Location.objects # TODO: Tmp
class CustomerProjectEditForm(forms.ModelForm): class CustomerProjectEditForm(forms.ModelForm):
@ -119,7 +116,9 @@ class CustomerProjectEditForm(forms.ModelForm):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.fields['realty'].empty_label = 'Создать новый' self.fields['realty'].empty_label = 'Создать новый'
self.fields['specialization'].queryset = Specialization.objects.root_nodes()[0].get_descendants()
# self.fields['specialization'].queryset = Specialization.objects.root_nodes()[0].get_descendants()
self.fields['specialization'].queryset = Specialization.objects # TODO: Tmp
if self.instance.pk: if self.instance.pk:
self.fields['files'].queryset = self.instance.files self.fields['files'].queryset = self.instance.files
@ -145,7 +144,8 @@ class RealtyForm(forms.ModelForm):
self.request = kwargs.pop('request') self.request = kwargs.pop('request')
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.fields['location'].queryset = Location.objects.root_nodes()[0].get_descendants() # self.fields['location'].queryset = Location.objects.root_nodes()[0].get_descendants()
self.fields['location'].queryset = Location.objects # TODO: Tmp
class Realty1Form(forms.Form): class Realty1Form(forms.Form):

@ -0,0 +1,114 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-21 15:08
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import mptt.fields
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('users', '0001_initial'),
('common', '0001_initial'),
('projects', '0001_initial'),
('specializations', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='realty',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='realties', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='projectfile',
name='project',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='files', to='projects.Project'),
),
migrations.AddField(
model_name='project',
name='customer',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='projects', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='project',
name='realty',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='projects', to='projects.Realty'),
),
migrations.AddField(
model_name='project',
name='specialization',
field=mptt.fields.TreeForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='projects', to='specializations.Specialization'),
),
migrations.AddField(
model_name='portfoliophoto',
name='portfolio',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='photos', to='projects.Portfolio'),
),
migrations.AddField(
model_name='portfolio',
name='building_classification',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='portfolios', to='projects.BuildingClassfication'),
),
migrations.AddField(
model_name='portfolio',
name='construction_type',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='portfolios', to='projects.ConstructionType'),
),
migrations.AddField(
model_name='portfolio',
name='location',
field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='portfolios', to='common.Location'),
),
migrations.AddField(
model_name='portfolio',
name='specialization',
field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='portfolios', to='specializations.Specialization'),
),
migrations.AddField(
model_name='portfolio',
name='team',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='portfolios', to='users.Team'),
),
migrations.AddField(
model_name='portfolio',
name='user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='portfolios', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='order',
name='contractor',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='orders', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='order',
name='project',
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='order', to='projects.Project'),
),
migrations.AddField(
model_name='candidate',
name='answer',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='candidates', to='projects.Answer'),
),
migrations.AddField(
model_name='candidate',
name='project',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='candidates', to='projects.Project'),
),
migrations.AddField(
model_name='answer',
name='contractor',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='answer',
name='project',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers', to='projects.Project'),
),
]

@ -0,0 +1,176 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-21 15:08
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import mptt.fields
class Migration(migrations.Migration):
initial = True
dependencies = [
('common', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Answer',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('budget', models.DecimalField(decimal_places=0, max_digits=10)),
('created', models.DateTimeField(default=django.utils.timezone.now)),
('currency', models.CharField(choices=[('rur', 'RUR'), ('usd', 'USD'), ('eur', 'EUR')], default='rur', max_length=5)),
('term', models.IntegerField(default=0)),
('term_type', models.CharField(choices=[('project', 'За проект'), ('hour', 'За час'), ('day', 'За день'), ('month', 'За месяц')], default='hour', max_length=10)),
('text', models.TextField()),
],
options={
'verbose_name': 'Ответ к проекту',
'ordering': ('-created',),
'verbose_name_plural': 'Ответы к проектам',
},
),
migrations.CreateModel(
name='BuildingClassfication',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
],
options={
'verbose_name': 'Тип здания',
'verbose_name_plural': 'Типы зданий',
},
),
migrations.CreateModel(
name='Candidate',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('status', models.BooleanField(default=False)),
],
options={
'verbose_name': 'Кандидат',
'verbose_name_plural': 'Кандидаты',
},
),
migrations.CreateModel(
name='ConstructionType',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
],
options={
'verbose_name': 'Вид строительства',
'verbose_name_plural': 'Виды строительства',
},
),
migrations.CreateModel(
name='Order',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(default=django.utils.timezone.now)),
('secure', models.BooleanField(default=False)),
('status', models.BooleanField(default=False)),
],
options={
'verbose_name': 'Заказ',
'verbose_name_plural': 'Заказы',
},
),
migrations.CreateModel(
name='Portfolio',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('budget', models.DecimalField(blank=True, decimal_places=0, default=0, max_digits=10, null=True)),
('currency', models.CharField(blank=True, choices=[('rur', 'RUR'), ('usd', 'USD'), ('eur', 'EUR')], default='rur', max_length=20, null=True)),
('description', models.TextField()),
('name', models.CharField(max_length=255)),
('term', models.IntegerField(blank=True, default=0, null=True)),
('term_type', models.CharField(blank=True, choices=[('project', 'За проект'), ('hour', 'За час'), ('day', 'За день'), ('month', 'За месяц')], default='hour', max_length=20, null=True)),
('worksell', models.BooleanField(default=False)),
],
options={
'verbose_name': 'Портфолио',
'verbose_name_plural': 'Портфолио',
},
),
migrations.CreateModel(
name='PortfolioPhoto',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('img', models.ImageField(upload_to='projects/portfolio')),
],
options={
'verbose_name': 'Фото портфолио',
'verbose_name_plural': 'Фото портфолио',
},
),
migrations.CreateModel(
name='Project',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('budget', models.DecimalField(decimal_places=0, max_digits=10)),
('budget_by_agreement', models.BooleanField(default=False)),
('created', models.DateTimeField(default=django.utils.timezone.now)),
('cro', models.BooleanField(default=False)),
('currency', models.CharField(choices=[('rur', 'RUR'), ('usd', 'USD'), ('eur', 'EUR')], default='rur', max_length=20)),
('deal_type', models.CharField(choices=[('secure_deal', 'Безопасная сделка (с резервированием бюджета) '), ('direct_payment', 'Прямая оплата Исполнителю на его кошелек/счет')], default='secure_deal', max_length=20)),
('name', models.CharField(max_length=255)),
('price_and_term_required', models.BooleanField(default=False)),
('state', models.CharField(choices=[('active', 'Активный'), ('trashed', 'В корзине'), ('deleted', 'Удален')], default='active', max_length=20)),
('term', models.IntegerField(default=0)),
('term_type', models.CharField(choices=[('project', 'За проект'), ('hour', 'За час'), ('day', 'За день'), ('month', 'За месяц')], default='hour', max_length=20)),
('text', models.TextField(blank=True)),
('work_type', models.IntegerField(choices=[(1, 'Проектирование'), (2, 'Техническое сопровождение')], default=1)),
],
options={
'verbose_name': 'Проект',
'verbose_name_plural': 'Проекты',
},
),
migrations.CreateModel(
name='ProjectFile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('file', models.FileField(upload_to='projects/project_files')),
],
options={
'verbose_name': 'Файл проекта',
'verbose_name_plural': 'Файлы проектов',
},
),
migrations.CreateModel(
name='Realty',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
('building_classification', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='realties', to='projects.BuildingClassfication')),
('construction_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='realties', to='projects.ConstructionType')),
('location', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='realties', to='common.Location')),
],
options={
'verbose_name': 'Объект',
'verbose_name_plural': 'Объекты',
},
),
migrations.CreateModel(
name='Stage',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('cost', models.DecimalField(decimal_places=0, max_digits=10)),
('cost_type', models.CharField(choices=[('rur', 'RUR'), ('usd', 'USD'), ('eur', 'EUR')], default='rur', max_length=5)),
('name', models.CharField(max_length=255)),
('result', models.CharField(max_length=255)),
('term', models.IntegerField(default=0)),
('term_type', models.CharField(choices=[('project', 'За проект'), ('hour', 'За час'), ('day', 'За день'), ('month', 'За месяц')], default='hour', max_length=10)),
('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='stages', to='projects.Order')),
],
options={
'verbose_name': 'Этап',
'verbose_name_plural': 'Этапы',
},
),
]

@ -0,0 +1,114 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-21 15:08
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import mptt.fields
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('users', '0001_initial'),
('common', '0001_initial'),
('projects', '0001_initial'),
('specializations', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='realty',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='realties', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='projectfile',
name='project',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='files', to='projects.Project'),
),
migrations.AddField(
model_name='project',
name='customer',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='projects', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='project',
name='realty',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='projects', to='projects.Realty'),
),
migrations.AddField(
model_name='project',
name='specialization',
field=mptt.fields.TreeForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='projects', to='specializations.Specialization'),
),
migrations.AddField(
model_name='portfoliophoto',
name='portfolio',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='photos', to='projects.Portfolio'),
),
migrations.AddField(
model_name='portfolio',
name='building_classification',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='portfolios', to='projects.BuildingClassfication'),
),
migrations.AddField(
model_name='portfolio',
name='construction_type',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='portfolios', to='projects.ConstructionType'),
),
migrations.AddField(
model_name='portfolio',
name='location',
field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='portfolios', to='common.Location'),
),
migrations.AddField(
model_name='portfolio',
name='specialization',
field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='portfolios', to='specializations.Specialization'),
),
migrations.AddField(
model_name='portfolio',
name='team',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='portfolios', to='users.Team'),
),
migrations.AddField(
model_name='portfolio',
name='user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='portfolios', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='order',
name='contractor',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='orders', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='order',
name='project',
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='order', to='projects.Project'),
),
migrations.AddField(
model_name='candidate',
name='answer',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='candidates', to='projects.Answer'),
),
migrations.AddField(
model_name='candidate',
name='project',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='candidates', to='projects.Project'),
),
migrations.AddField(
model_name='answer',
name='contractor',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='answer',
name='project',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers', to='projects.Project'),
),
]

@ -1,9 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-05-19 10:22 # Generated by Django 1.9.7 on 2016-07-21 15:08
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
import django.utils.timezone
import mptt.fields
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -11,6 +13,7 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
('common', '0001_initial'),
] ]
operations = [ operations = [
@ -18,44 +21,156 @@ class Migration(migrations.Migration):
name='Answer', name='Answer',
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('cost', models.DecimalField(decimal_places=2, max_digits=10)), ('budget', models.DecimalField(decimal_places=0, max_digits=10)),
('cost_type', models.CharField(choices=[('RUR', 'rur'), ('USD', 'usd'), ('EUR', 'eur')], default='RUR', max_length=5)), ('created', models.DateTimeField(default=django.utils.timezone.now)),
('currency', models.CharField(choices=[('rur', 'RUR'), ('usd', 'USD'), ('eur', 'EUR')], default='rur', max_length=5)),
('term', models.IntegerField(default=0)),
('term_type', models.CharField(choices=[('project', 'За проект'), ('hour', 'За час'), ('day', 'За день'), ('month', 'За месяц')], default='hour', max_length=10)),
('text', models.TextField()), ('text', models.TextField()),
('term', models.DecimalField(decimal_places=2, max_digits=10)),
('term_type', models.CharField(choices=[('HOUR', 'hour'), ('DAY', 'day'), ('MONTH', 'month')], default='hour', max_length=10)),
], ],
options={ options={
'verbose_name': 'Ответ к проекту', 'verbose_name': 'Ответ к проекту',
'ordering': ('-created',),
'verbose_name_plural': 'Ответы к проектам', 'verbose_name_plural': 'Ответы к проектам',
}, },
), ),
migrations.CreateModel( migrations.CreateModel(
name='Portfolio', name='BuildingClassfication',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
],
options={
'verbose_name': 'Тип здания',
'verbose_name_plural': 'Типы зданий',
},
),
migrations.CreateModel(
name='Candidate',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('status', models.BooleanField(default=False)),
],
options={
'verbose_name': 'Кандидат',
'verbose_name_plural': 'Кандидаты',
},
),
migrations.CreateModel(
name='ConstructionType',
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)), ('name', models.CharField(max_length=255)),
],
options={
'verbose_name': 'Вид строительства',
'verbose_name_plural': 'Виды строительства',
},
),
migrations.CreateModel(
name='Order',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(default=django.utils.timezone.now)),
('secure', models.BooleanField(default=False)),
('status', models.BooleanField(default=False)),
],
options={
'verbose_name': 'Заказ',
'verbose_name_plural': 'Заказы',
},
),
migrations.CreateModel(
name='Portfolio',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('budget', models.DecimalField(blank=True, decimal_places=0, default=0, max_digits=10, null=True)),
('currency', models.CharField(blank=True, choices=[('rur', 'RUR'), ('usd', 'USD'), ('eur', 'EUR')], default='rur', max_length=20, null=True)),
('description', models.TextField()), ('description', models.TextField()),
('name', models.CharField(max_length=255)),
('term', models.IntegerField(blank=True, default=0, null=True)),
('term_type', models.CharField(blank=True, choices=[('project', 'За проект'), ('hour', 'За час'), ('day', 'За день'), ('month', 'За месяц')], default='hour', max_length=20, null=True)),
('worksell', models.BooleanField(default=False)),
], ],
options={
'verbose_name': 'Портфолио',
'verbose_name_plural': 'Портфолио',
},
), ),
migrations.CreateModel( migrations.CreateModel(
name='PortfolioPhoto', name='PortfolioPhoto',
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('img', models.ImageField(upload_to='projects/portfolio')), ('img', models.ImageField(upload_to='projects/portfolio')),
('portfolio', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='projects.Portfolio')),
], ],
options={
'verbose_name': 'Фото портфолио',
'verbose_name_plural': 'Фото портфолио',
},
), ),
migrations.CreateModel( migrations.CreateModel(
name='Project', name='Project',
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('budget', models.DecimalField(decimal_places=0, max_digits=10)),
('budget_by_agreement', models.BooleanField(default=False)),
('created', models.DateTimeField(default=django.utils.timezone.now)),
('cro', models.BooleanField(default=False)),
('currency', models.CharField(choices=[('rur', 'RUR'), ('usd', 'USD'), ('eur', 'EUR')], default='rur', max_length=20)),
('deal_type', models.CharField(choices=[('secure_deal', 'Безопасная сделка (с резервированием бюджета) '), ('direct_payment', 'Прямая оплата Исполнителю на его кошелек/счет')], default='secure_deal', max_length=20)),
('name', models.CharField(max_length=255)), ('name', models.CharField(max_length=255)),
('price', models.DecimalField(decimal_places=2, max_digits=10)), ('price_and_term_required', models.BooleanField(default=False)),
('state', models.CharField(choices=[('active', 'Активный'), ('trashed', 'В корзине'), ('deleted', 'Удален')], default='active', max_length=20)),
('term', models.IntegerField(default=0)),
('term_type', models.CharField(choices=[('project', 'За проект'), ('hour', 'За час'), ('day', 'За день'), ('month', 'За месяц')], default='hour', max_length=20)),
('text', models.TextField(blank=True)), ('text', models.TextField(blank=True)),
('work_type', models.IntegerField(choices=[(1, 'Проектирование'), (2, 'Техническое сопровождение')], default=1)),
], ],
options={ options={
'verbose_name': 'Проект', 'verbose_name': 'Проект',
'verbose_name_plural': 'Проекты', 'verbose_name_plural': 'Проекты',
}, },
), ),
migrations.CreateModel(
name='ProjectFile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('file', models.FileField(upload_to='projects/project_files')),
],
options={
'verbose_name': 'Файл проекта',
'verbose_name_plural': 'Файлы проектов',
},
),
migrations.CreateModel(
name='Realty',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
('building_classification', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='realties', to='projects.BuildingClassfication')),
('construction_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='realties', to='projects.ConstructionType')),
('location', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='realties', to='common.Location')),
],
options={
'verbose_name': 'Объект',
'verbose_name_plural': 'Объекты',
},
),
migrations.CreateModel(
name='Stage',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('cost', models.DecimalField(decimal_places=0, max_digits=10)),
('cost_type', models.CharField(choices=[('rur', 'RUR'), ('usd', 'USD'), ('eur', 'EUR')], default='rur', max_length=5)),
('name', models.CharField(max_length=255)),
('result', models.CharField(max_length=255)),
('term', models.IntegerField(default=0)),
('term_type', models.CharField(choices=[('project', 'За проект'), ('hour', 'За час'), ('day', 'За день'), ('month', 'За месяц')], default='hour', max_length=10)),
('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='stages', to='projects.Order')),
],
options={
'verbose_name': 'Этап',
'verbose_name_plural': 'Этапы',
},
),
] ]

@ -3,9 +3,10 @@ from datetime import datetime
from django.db import models from django.db import models
from django.utils import timezone from django.utils import timezone
from users.models import User from users.models import User, Team
from specializations.models import Specialization from specializations.models import Specialization
CURRENCIES = ( CURRENCIES = (
('rur', 'RUR'), ('rur', 'RUR'),
('usd', 'USD'), ('usd', 'USD'),
@ -19,6 +20,7 @@ TERMS = (
('month', 'За месяц'), ('month', 'За месяц'),
) )
class BuildingClassfication(models.Model): class BuildingClassfication(models.Model):
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
@ -79,16 +81,16 @@ class Project(models.Model):
cro = models.BooleanField(default=False) cro = models.BooleanField(default=False)
currency = models.CharField(max_length=20, default='rur', choices=CURRENCIES) currency = models.CharField(max_length=20, default='rur', choices=CURRENCIES)
customer = models.ForeignKey(User, related_name='projects') customer = models.ForeignKey(User, related_name='projects')
deal_type = models.CharField(max_length=20, default='secure_deal', choices=DEAL_TYPES)
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
price_and_term_required = models.BooleanField(default=False) price_and_term_required = models.BooleanField(default=False)
realty = models.ForeignKey(Realty, blank=True, null=True, related_name='projects') realty = models.ForeignKey(Realty, blank=True, null=True, related_name='projects')
deal_type = models.CharField(max_length=20, default='secure_deal', choices=DEAL_TYPES)
specialization = TreeForeignKey(Specialization, related_name='projects') specialization = TreeForeignKey(Specialization, related_name='projects')
state = models.CharField(default='active', max_length=20, choices=STATES)
term = models.IntegerField(default=0) term = models.IntegerField(default=0)
term_type = models.CharField(max_length=20, choices=TERMS, default='hour') term_type = models.CharField(max_length=20, choices=TERMS, default='hour')
text = models.TextField(blank=True) text = models.TextField(blank=True)
work_type = models.IntegerField(default=1, choices=WORK_TYPES) work_type = models.IntegerField(default=1, choices=WORK_TYPES)
state = models.CharField(default='active', max_length=20, choices=STATES)
def __str__(self): def __str__(self):
return self.name return self.name
@ -115,13 +117,13 @@ class ProjectFile(models.Model):
class Answer(models.Model): class Answer(models.Model):
budget = models.DecimalField(max_digits=10, decimal_places=0) budget = models.DecimalField(max_digits=10, decimal_places=0)
currency = models.CharField(max_length=5, choices=CURRENCIES, default='rur') contractor = models.ForeignKey(User, related_name='answers')
created = models.DateTimeField(default=timezone.now) created = models.DateTimeField(default=timezone.now)
currency = models.CharField(max_length=5, choices=CURRENCIES, default='rur')
project = models.ForeignKey(Project, related_name='answers') project = models.ForeignKey(Project, related_name='answers')
term = models.IntegerField(default=0) term = models.IntegerField(default=0)
term_type = models.CharField(max_length=10, choices=TERMS, default='hour') term_type = models.CharField(max_length=10, choices=TERMS, default='hour')
text = models.TextField() text = models.TextField()
contractor = models.ForeignKey(User, related_name='answers')
def __str__(self): def __str__(self):
return self.text return self.text
@ -178,18 +180,19 @@ class Candidate(models.Model):
class Portfolio(models.Model): class Portfolio(models.Model):
description = models.TextField()
name = models.CharField(max_length=255)
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 = models.ForeignKey(BuildingClassfication, related_name='portfolios', null=True, blank=True)
construction_type = models.ForeignKey(ConstructionType, related_name='portfolios', null=True, blank=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)
specialization = TreeForeignKey(Specialization, related_name='portfolios',null=True, blank=True) description = models.TextField()
term = models.IntegerField(default=0,null=True, blank=True)
term_type = models.CharField(max_length=20, choices=TERMS, default='hour',null=True, blank=True)
building_classification = models.ForeignKey(BuildingClassfication, related_name='portfolios',null=True, blank=True)
construction_type = models.ForeignKey(ConstructionType, related_name='portfolios',null=True, blank=True)
location = TreeForeignKey('common.Location', related_name='portfolios', null=True, blank=True) location = TreeForeignKey('common.Location', related_name='portfolios', null=True, blank=True)
name = models.CharField(max_length=255)
specialization = TreeForeignKey(Specialization, related_name='portfolios', null=True, blank=True)
team = models.ForeignKey(Team, related_name='portfolios', null=True, blank=True)
term = models.IntegerField(default=0, null=True, blank=True)
term_type = models.CharField(max_length=20, choices=TERMS, default='hour', null=True, blank=True)
user = models.ForeignKey(User, related_name='portfolios', null=True, blank=True)
worksell = models.BooleanField(default=False) worksell = models.BooleanField(default=False)
user = models.ForeignKey(User, related_name='portfolios')
def __str__(self): def __str__(self):
return self.name return self.name
@ -199,20 +202,17 @@ class Portfolio(models.Model):
verbose_name_plural = 'Портфолио' verbose_name_plural = 'Портфолио'
def get_cover(self): def get_cover(self):
cover = None photo = self.photos.first()
all_photos = self.portfoliophoto_set.all() return photo and photo.img.url
if all_photos:
cover = all_photos[0].img
return cover
class PortfolioPhoto(models.Model): class PortfolioPhoto(models.Model):
img = models.ImageField(upload_to='projects/portfolio') img = models.ImageField(upload_to='projects/portfolio')
portfolio = models.ForeignKey(Portfolio) portfolio = models.ForeignKey(Portfolio, related_name='photos')
class Meta: class Meta:
verbose_name = 'Фото портфолио' verbose_name = 'Фото портфолио'
verbose_name_plural = 'Фото портфолио' verbose_name_plural = 'Фото портфолио'
# def __str__(self): def __str__(self):
# return self.img return self.img and self.img.url or str(self.img)

@ -13,7 +13,7 @@
<form action="{% url 'projects:project-filter' %}" method="GET" novalidate> <form action="{% url 'projects:project-filter' %}" method="GET" novalidate>
<div class="col-lg-12"> <div class="col-lg-12">
<div class="filter clearfix"> --<div class="filter clearfix">
<div class="triangle1"></div> <div class="triangle1"></div>
@ -191,13 +191,16 @@
<p class="textPro">{{ proj.text }}</p> <p class="textPro">{{ proj.text }}</p>
{% if TEMPLATE_DEBUG %} {% if TEMPLATE_DEBUG %}
<pre class="textPro"><!-- <pre><!--
-->{{ proj|inspect }}<br><!-- -->{{ proj|inspect }}<br><!--
--><br><!-- --><br><!--
-->Specialization: {{ proj.specialization }}<br><!-- --><b>Specialization:</b> {{ proj.specialization }}<br><!--
-->Realty location: {{ proj.realty.location }}<br><!-- --><br><!--
-->Constr. type: {{ proj.realty.construction_type }}<br><!-- --><b>Realty location:</b> {{ proj.realty.location }}<br><!--
-->Build. classif.: {{ proj.realty.building_classification }}<br><!-- --><br><!--
--><b>Constr. type:</b> {{ proj.realty.construction_type }}<br><!--
--><br><!--
--><b>Build. classif.:</b> {{ proj.realty.building_classification }}<br><!--
--></pre> --></pre>
{% endif %} {% endif %}
@ -234,44 +237,14 @@
<div class="col-lg-12 pagin"> <div class="col-lg-12 pagin">
{% if is_paginated %} {% include 'partials/pagination.html' %}
<nav>
<ul class="pagination">
{% if projects.has_previous %}
<li>
<button type="submit" name="page" value="{{ projects.previous_page_number }}">Previous</button>
</li>
{% endif %}
{% for n in projects.paginator.page_range %}
{% if n == projects.number %}
<li class="i active">
<button type="submit" name="page" value="{{ n }}" class="i" disabled>{{ n }}</button>
</li>
{% else %}
<li>
<button type="submit" name="page" value="{{ n }}">{{ n }}</button>
</li>
{% endif %}
{% endfor %}
{% if projects.has_next %}
<li>
<button type="submit" name="page" value="{{ projects.next_page_number }}">Next</button>
</li>
{% endif %}
</ul>
</nav>
{% else %}
{% include 'partials/pagination.html' %}
{% endif %}
</div> </div>
</form> </form>
{% include 'partials/footer.html' %} {% include 'partials/footer.html' %}
</div> </div>
</div> </div>

@ -10,7 +10,7 @@ from django.views.generic import ListView, DetailView, CreateView, View, UpdateV
from django.views.generic.base import ContextMixin from django.views.generic.base import ContextMixin
from pprint import pprint, pformat from pprint import pprint, pformat
import json import json
import pydash as _ import pydash as _; _.map = _.map_; _.filter = _.filter_
import re import re
from .mixins import LastAccessMixin from .mixins import LastAccessMixin
@ -45,6 +45,8 @@ class ProjectFilterView(BaseMixin, View):
projects = Project.objects projects = Project.objects
if form.is_valid() and realty_form.is_valid(): if form.is_valid() and realty_form.is_valid():
ord = None
keywords = form.cleaned_data.get('keywords') keywords = form.cleaned_data.get('keywords')
cro = form.cleaned_data.get('cro') cro = form.cleaned_data.get('cro')
work_type = form.cleaned_data.get('work_type') work_type = form.cleaned_data.get('work_type')
@ -88,15 +90,14 @@ class ProjectFilterView(BaseMixin, View):
reverse_order = form.cleaned_data.get('reverse_order') reverse_order = form.cleaned_data.get('reverse_order')
if order_by: if order_by:
if order_by == last_order_by: reverse_order = not reverse_order if order_by == last_order_by else False
reverse_order = not reverse_order ord = order_by
else: last_order_by = ord
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: elif last_order_by:
projects = projects.order_by('-%s' % last_order_by if reverse_order else last_order_by) ord = last_order_by
if ord:
projects = projects.order_by('-%s' % ord if reverse_order else ord)
context.update({ context.update({
'last_order_by': last_order_by, 'last_order_by': last_order_by,
@ -131,13 +132,12 @@ class ProjectFilterView(BaseMixin, View):
except EmptyPage: except EmptyPage:
projects = paginator.page(paginator.num_pages) projects = paginator.page(paginator.num_pages)
# import code; code.interact(local=dict(globals(), **locals()))
context.update({ context.update({
'form': form, 'form': form,
'realty_form': realty_form, 'realty_form': realty_form,
'projects': projects, 'projects': projects,
'is_paginated': True, 'is_paginated': True,
'page_obj': projects,
'display_msg': display_msg, 'display_msg': display_msg,
}) })

@ -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

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-21 15:08
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('reviews', '0001_initial'),
('projects', '0002_auto_20160721_1808'),
]
operations = [
migrations.AddField(
model_name='review',
name='from_contractor',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='customer_reviews', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='review',
name='from_customer',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='contractor_reviews', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='review',
name='project',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reviews', to='projects.Project'),
),
migrations.AddField(
model_name='review',
name='target_contractor',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reviews_by_customer', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='review',
name='target_customer',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reviews_by_contractor', to=settings.AUTH_USER_MODEL),
),
]

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-21 15:08
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('reviews', '0001_initial'),
('projects', '0002_auto_20160721_1808'),
]
operations = [
migrations.AddField(
model_name='review',
name='from_contractor',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='customer_reviews', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='review',
name='from_customer',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='contractor_reviews', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='review',
name='project',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reviews', to='projects.Project'),
),
migrations.AddField(
model_name='review',
name='target_contractor',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reviews_by_customer', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='review',
name='target_customer',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reviews_by_contractor', to=settings.AUTH_USER_MODEL),
),
]

@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-21 17:21
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('reviews', '0002_auto_20160721_1808'),
]
operations = [
migrations.AlterField(
model_name='review',
name='from_contractor',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='customer_reviews', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='review',
name='from_customer',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='contractor_reviews', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='review',
name='target_contractor',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reviews_by_customer', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='review',
name='target_customer',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reviews_by_contractor', to=settings.AUTH_USER_MODEL),
),
migrations.AlterUniqueTogether(
name='review',
unique_together=set([('from_customer', 'target_contractor', 'project'), ('from_contractor', 'target_customer', 'project')]),
),
]

@ -1,11 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-05-31 08:46 # Generated by Django 1.9.7 on 2016-07-21 15:08
from __future__ import unicode_literals from __future__ import unicode_literals
from django.conf import settings
import django.core.validators import django.core.validators
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -13,7 +11,6 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
] ]
operations = [ operations = [
@ -21,10 +18,13 @@ class Migration(migrations.Migration):
name='Review', name='Review',
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('text', models.TextField()),
('stars', models.IntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(5)])),
('is_secured', models.BooleanField(default=False)), ('is_secured', models.BooleanField(default=False)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reviews', to=settings.AUTH_USER_MODEL)), ('stars', models.IntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(5)])),
('text', models.TextField()),
], ],
options={
'verbose_name': 'Отзыв',
'verbose_name_plural': 'Отзывы',
},
), ),
] ]

@ -2,15 +2,23 @@ from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator from django.core.validators import MaxValueValidator, MinValueValidator
class Review(models.Model): class Review(models.Model):
text = models.TextField()
project = models.ForeignKey("projects.Project", related_name='reviews')
user = models.ForeignKey("users.User", related_name='reviews')
stars = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(5)])
is_secured = models.BooleanField(default=False) is_secured = models.BooleanField(default=False)
project = models.ForeignKey('projects.Project', related_name='reviews')
stars = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(5)])
text = models.TextField()
target_customer = models.ForeignKey('users.User', related_name='reviews_by_contractor', null=True, blank=True)
target_contractor = models.ForeignKey('users.User', related_name='reviews_by_customer', null=True, blank=True)
from_customer = models.ForeignKey('users.User', related_name='contractor_reviews', null=True, blank=True)
from_contractor = models.ForeignKey('users.User', related_name='customer_reviews', null=True, blank=True)
def __str__(self): def __str__(self):
return self.pk return str(self.pk)
class Meta: class Meta:
verbose_name = 'Отзыв' verbose_name = 'Отзыв'
verbose_name_plural = 'Отзывы' verbose_name_plural = 'Отзывы'
unique_together = (
('from_customer', 'target_contractor', 'project'),
('from_contractor', 'target_customer', 'project'),
)

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-21 15:08
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import mptt.fields
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Specialization',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('lft', models.PositiveIntegerField(db_index=True, editable=False)),
('rght', models.PositiveIntegerField(db_index=True, editable=False)),
('tree_id', models.PositiveIntegerField(db_index=True, editable=False)),
('level', models.PositiveIntegerField(db_index=True, editable=False)),
('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='specializations.Specialization')),
],
options={
'verbose_name': 'Специализация',
'verbose_name_plural': 'Специализации',
},
),
]

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-05-19 10:22 # Generated by Django 1.9.7 on 2016-07-21 15:08
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
@ -27,7 +27,8 @@ class Migration(migrations.Migration):
('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='specializations.Specialization')), ('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='specializations.Specialization')),
], ],
options={ options={
'abstract': False, 'verbose_name': 'Специализация',
'verbose_name_plural': 'Специализации',
}, },
), ),
] ]

@ -14,7 +14,10 @@ class SpecListView(ListView):
root = Specialization.objects.get(pk=1) root = Specialization.objects.get(pk=1)
context['root'] = root context['root'] = root
context['children'] = root.get_children() context['children'] = root.get_children()
context['roots'] = Specialization.objects.root_nodes()
# context['roots'] = Specialization.objects.root_nodes()
context['roots'] = Specialization.objects.filter(name='_root') # TODO: Tmp
return context return context

@ -9,10 +9,10 @@
{# {% url "password_reset_recover" %}#} {# {% url "password_reset_recover" %}#}
<p class="welcomeMain">Основная задача сайта</p> <p class="welcomeMain">Основная задача сайта</p>
<p> <p style="font-size: 25px; line-height: initial; font-weight: bold">
Authed? {{ request.user.is_authenticated }}c Authed? {{ request.user.is_authenticated }}<br>
{{ request.user }}<br> {{ request.user }} ({{ request.user.pk }})<br>
{{ request.user.groups.all }} {{ request.user.groups.all }}<br>
</p> </p>
</div> </div>
</div> </div>

@ -1,131 +1,137 @@
{% load staticfiles %} {% load staticfiles %}
{% load thumbnail %} {% load thumbnail %}
<div class="wrTop {% if request.user.is_authenticated %} disTab {% endif %}">
<div class="container-fluid topMain"> <div class="wrTop {% if request.user.is_authenticated %} disTab {% endif %}">
<div class="row"> <div class="container-fluid topMain">
<div class="col-lg-3"> <div class="row">
<div class="logo" onClick="window.location='/'"></div> <div class="col-lg-3">
</div> <div class="logo" onClick="window.location='/'"></div>
{% if request.user.is_authenticated %} </div>
<div class="col-lg-7">
<ul class="mainMenu"> {% if request.user.is_authenticated %}
<li class="icon_tm1"> <div class="col-lg-7">
<a href="{% url 'projects:project-filter' %}">Биржа проектов</a> <ul class="mainMenu">
<span></span> <li class="icon_tm1">
</li> <a href="{% url 'projects:project-filter' %}">Биржа проектов</a>
<span></span>
</li>
{% if request.user.is_contractor %} {% if request.user.is_contractor %}
<li class="officeList icon_tml"> <li class="officeList icon_tml">
<a href="{% url 'users:contractor-office' pk=request.user.pk %}">Мой офис</a> <a href="{% url 'users:contractor-office' pk=request.user.pk %}">Мой офис</a>
<span></span> <span></span>
</li> </li>
{% endif%} {% endif%}
{% if request.user.is_customer %} {% if request.user.is_customer %}
<li class="icon_tm2"> <li class="icon_tm2">
<a href="{% url 'users:contractor-list' %}">Поиск исполнителей</a> <a href="{% url 'users:contractor-filter' %}">Поиск исполнителей</a>
<span></span> <span></span>
</li> </li>
<li class="icon_tm3"> <li class="icon_tm3">
<a href="{% url 'users:contractor-list' %}">Работы на продажу</a> <a href="#">Работы на продажу</a>
<span></span> <span></span>
</li> </li>
{% endif %} {% endif %}
</ul> </ul>
</div> </div>
{% else %} {% else %}
<div class="col-lg-7"> <div class="col-lg-7">
<ul class="mainMenu"> <ul class="mainMenu">
<li class="icon_tm1"> <li class="icon_tm1">
<a href="{% url 'projects:project-filter' %}">Биржа проектов</a> <a href="{% url 'projects:project-filter' %}">Биржа проектов</a>
<span></span> <span></span>
</li> </li>
<li class="icon_tm2"> <li class="icon_tm2">
<a href="{% url 'users:contractor-list' %}">Поиск исполнителей</a> <a href="{% url 'users:contractor-filter' %}">Поиск исполнителей</a>
<span></span> <span></span>
</li> </li>
<li class="icon_tm3"> <li class="icon_tm3">
<a href="{% url 'users:contractor-list' %}">Работы на продажу</a> <a href="#">Работы на продажу</a>
<span></span> <span></span>
</li> </li>
</ul> </ul>
</div> </div>
{% endif %} {% endif %}
{% if request.user.is_authenticated %}
<div class="col-lg-2"> {% if request.user.is_authenticated %}
<div class="imgProfile"> <div class="col-lg-2">
{% if request.user.is_contractor %} <div class="imgProfile">
<a href="{% url 'users:contractor-profile' pk=request.user.pk %}"> {% if request.user.is_contractor %}
{% thumbnail request.user.avatar "75x75" crop="center" as im %} <a href="{% url 'users:contractor-profile' pk=request.user.pk %}">
<img src="{{ im.url }}" alt="profile-image"> {% thumbnail request.user.avatar "75x75" crop="center" as im %}
{% endthumbnail %} <img src="{{ im.url }}" alt="profile-image">
</a> {% endthumbnail %}
{% elif request.user.is_customer %} </a>
<a href="{% url 'users:customer-profile-open-projects' pk=request.user.pk %}"> {% elif request.user.is_customer %}
{% thumbnail request.user.avatar "75x75" crop="center" as im %} <a href="{% url 'users:customer-profile-open-projects' pk=request.user.pk %}">
<img src="{{ im.url }}" alt="profile-image"> {% thumbnail request.user.avatar "75x75" crop="center" as im %}
{% endthumbnail %} <img src="{{ im.url }}" alt="profile-image">
</a> {% endthumbnail %}
{% endif %} </a>
</div> {% endif %}
<div class="infoProfile disTab"> </div>
<div class="btn-group" role="group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <div class="infoProfile disTab">
<span class="glyphicon glyphicon-menu-hamburger" aria-hidden="true"></span> <div class="btn-group" role="group">
</button> <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<ul class="dropdown-menu menu-drop-new"> <span class="glyphicon glyphicon-menu-hamburger" aria-hidden="true"></span>
<li class="icon_mm1"> </button>
<a href="{% url 'auth_login' %}"> <ul class="dropdown-menu menu-drop-new">
Войти заказчиком <li class="icon_mm1">
<span></span> <a href="{% url 'auth_login' %}">
</a> Войти заказчиком
</li> <span></span>
<li class="icon_mm2"> </a>
<a href="{% url 'auth_login' %}"> </li>
Войти исполнителем <li class="icon_mm2">
<span></span> <a href="{% url 'auth_login' %}">
</a> Войти исполнителем
</li> <span></span>
<li class="icon_mm3"> </a>
<a href="#"> </li>
Сообщения <li class="icon_mm3">
<span></span> <a href="#">
</a> Сообщения
</li> <span></span>
<li class="icon_mm4"> </a>
<a href="#"> </li>
Счет <li class="icon_mm4">
<span></span> <a href="#">
</a> Счет
</li> <span></span>
<li class="icon_mm5"> </a>
<a href="#"> </li>
Настройки <li class="icon_mm5">
<span></span> <a href="#">
</a> Настройки
</li> <span></span>
<li class="icon_mm6"> </a>
<a href="#"> </li>
FAQ <li class="icon_mm6">
<span></span> <a href="#">
</a> FAQ
</li> <span></span>
</ul> </a>
</div> </li>
</div> </ul>
</div>
</div>
{% if request.user.is_contractor %} {% if request.user.is_contractor %}
<div class="rating"> <div class="rating">
<div class="ratingInset"></div> <div class="ratingInset"></div>
<div class="iconRating"></div> <div class="iconRating"></div>
</div> </div>
<p class="ratingPer">45%</p> <p class="ratingPer">45%</p>
{% endif %} {% endif %}
</div> </div>
{% else %} {% else %}
<div class="col-lg-2"> <div class="col-lg-2">
<a href="{% url 'registration_register' %}" class="reg">Регистрация</a> <a href="{% url 'registration_register' %}" class="reg">Регистрация</a>
<div class="lock"></div> <div class="lock"></div>
</div> </div>
{% endif %} {% endif %}
</div> </div>
</div> </div>
</div> </div>

@ -1,21 +1,29 @@
<nav> {% if is_paginated %}
<ul class="pagination"> <nav>
<li> <ul class="pagination">
<a href="#" aria-label="Previous"> {% if page_obj.has_previous %}
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> <li>
</a> <button type="submit" name="page" value="{{ page_obj.previous_page_number }}">Previous</button>
</li> </li>
<li class="active"><a href="#">1</a></li> {% endif %}
<li><a href="#">2</a></li>
<li><a href="#">3</a></li> {% for n in page_obj.paginator.page_range %}
<li><a href="#">4</a></li> {% if n == page_obj.number %}
<li><a href="#">5</a></li> <li class="i active">
<li>...</li> <button type="submit" name="page" value="{{ n }}" class="i" disabled>{{ n }}</button>
<li><a href="#">17</a></li> </li>
<li> {% else %}
<a href="#" aria-label="Next"> <li>
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> <button type="submit" name="page" value="{{ n }}">{{ n }}</button>
</a> </li>
</li> {% endif %}
</ul> {% endfor %}
</nav>
{% if page_obj.has_next %}
<li>
<button type="submit" name="page" value="{{ page_obj.next_page_number }}">Next</button>
</li>
{% endif %}
</ul>
</nav>
{% endif %}

@ -21,6 +21,7 @@
<div class="col-lg-3"> <div class="col-lg-3">
<div class="logo" onClick="window.location='/'"></div> <div class="logo" onClick="window.location='/'"></div>
</div> </div>
<div class="col-lg-7"> <div class="col-lg-7">
<ul class="mainMenu"> <ul class="mainMenu">
<li class="icon_tm1"> <li class="icon_tm1">
@ -37,6 +38,7 @@
</li> </li>
</ul> </ul>
</div> </div>
<div class="mLeft"> <div class="mLeft">
<div class="imgProfile"> <div class="imgProfile">
<img src="img/profile.jpg" alt="profile-image"> <img src="img/profile.jpg" alt="profile-image">
@ -95,11 +97,15 @@
</div> </div>
</div> </div>
</div> </div>
<div class="container mainScore"> <div class="container mainScore">
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<p class="titleScore">Поиск исполнителей</p> <p class="titleScore">Поиск исполнителей</p>
</div> </div>
<div class="col-lg-12"> <div class="col-lg-12">
<div class="filter clearfix"> <div class="filter clearfix">
<div class="triangle1"></div> <div class="triangle1"></div>
@ -171,6 +177,7 @@
</div> </div>
</div> </div>
</div> </div>
<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> <button type="button" class="btn btn-default">Все</button>
@ -187,6 +194,7 @@
</div> </div>
</div> </div>
</div> </div>
<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">
@ -305,6 +313,7 @@
</div> </div>
</div> </div>
</div> </div>
<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">
@ -423,6 +432,7 @@
</div> </div>
</div> </div>
</div> </div>
<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">
@ -541,6 +551,7 @@
</div> </div>
</div> </div>
</div> </div>
<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">
@ -659,6 +670,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col-lg-12 pagin"> <div class="col-lg-12 pagin">
<nav> <nav>
<ul class="pagination"> <ul class="pagination">
@ -682,6 +694,7 @@
</ul> </ul>
</nav> </nav>
</div> </div>
<footer class="disTab"> <footer class="disTab">
<div class="col-lg-4"> <div class="col-lg-4">
<div class="logoF" onclick="window.location='/'"></div> <div class="logoF" onclick="window.location='/'"></div>
@ -734,10 +747,14 @@
</footer> </footer>
</div> </div>
</div> </div>
<script src="js/jquery-2.2.3.min.js"></script> <script src="js/jquery-2.2.3.min.js"></script>
<script src="js/bootstrap.min.js"></script> <script src="js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.10.0/js/bootstrap-select.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.10.0/js/bootstrap-select.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.10.0/js/i18n/defaults-*.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.10.0/js/i18n/defaults-*.min.js"></script>
<script src="js/main.js"></script> <script src="js/main.js"></script>
</body> </body>
</html> </html>

@ -1,20 +1,24 @@
from django import forms from django import forms
from django.forms import ModelForm from django.forms import ModelForm
import itertools
from specializations.models import Specialization
from .models import User, ContractorFinancialInfo from .models import User, ContractorFinancialInfo
from common.models import Location
from projects.models import Project, BuildingClassfication, ConstructionType
from specializations.models import Specialization
class UserEditForm(ModelForm): class UserEditForm(ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
# import code; code.interact(local=dict(globals(), **locals()))
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if kwargs.get('instance'): if kwargs.get('instance'):
if kwargs.get('instance').is_contractor(): if kwargs.get('instance').is_contractor():
self.fields['contractor_specializations'].queryset = kwargs.get('instance').contractor_specializations.all() self.fields['contractor_specializations'].queryset = kwargs.get('instance').contractor_specializations.all()
class Meta: class Meta:
model = User model = User
fields = ( fields = (
'first_name', 'first_name',
'last_name', 'last_name',
@ -36,8 +40,77 @@ class UserEditForm(ModelForm):
} }
class ContractorFinancicalInfoForm(ModelForm): class ContractorFilterForm(forms.Form):
CONTRACTOR_ORDER_CHOICES = (
('', 'Сортировать по...'),
('name', 'Названию'),
('created', 'Дате размещения'),
('views', 'Просмотрам'),
('reviews', 'Отзывам'),
('rating', 'Рейтингу'),
# ('project_number', 'Кол-ву выполн. проектов'),
)
PARTY_TYPES = (
('all', 'Все'),
('teams', 'Группы'),
('contractors', 'Исполнители'),
)
order_by = forms.ChoiceField(required=False, choices=CONTRACTOR_ORDER_CHOICES)
last_order_by = forms.ChoiceField(required=False, choices=CONTRACTOR_ORDER_CHOICES)
reverse_order = forms.BooleanField(required=False)
specialization = forms.ModelChoiceField(
# queryset=Specialization.objects.root_nodes()[0].get_descendants(),
queryset=Specialization.objects, # TODO: Tmp,
required=False,
)
location = forms.ModelChoiceField(
# queryset=Location.objects.root_nodes()[0].get_descendants(),
queryset=Location.objects, # TODO: Tmp
required=False,
)
building_classification = forms.ModelChoiceField(
queryset=BuildingClassfication.objects,
widget=forms.Select(attrs={'class': 'selectpicker'}),
required=False,
empty_label='',
)
work_type = forms.ChoiceField(
choices=tuple(itertools.chain((('',''),), Project.WORK_TYPES)),
widget=forms.Select(attrs={'class': 'selectpicker'}),
required=False,
)
construction_type = forms.ModelChoiceField(
queryset=ConstructionType.objects,
widget=forms.Select(attrs={'class': 'selectpicker'}),
required=False,
empty_label='',
)
cro = forms.BooleanField(required=False)
party_types = forms.ChoiceField(
choices=PARTY_TYPES,
required=False,
)
last_party_types = forms.ChoiceField(
choices=PARTY_TYPES,
required=False,
)
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
super().__init__(*args, **kwargs)
class ContractorFinancicalInfoForm(ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.fields['residency'].choices = self.fields['residency'].choices[1:] self.fields['residency'].choices = self.fields['residency'].choices[1:]
@ -48,6 +121,7 @@ class ContractorFinancicalInfoForm(ModelForm):
class Meta: class Meta:
model = ContractorFinancialInfo model = ContractorFinancialInfo
fields = ( fields = (
'fio', 'fio',
'date_of_birth', 'date_of_birth',

@ -0,0 +1,149 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-21 15:08
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import mptt.fields
class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0007_alter_validators_add_error_messages'),
('common', '0001_initial'),
('specializations', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='User',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('avatar', models.ImageField(blank=True, upload_to='users/avatars/')),
('contractor_status', models.CharField(choices=[('free', 'Свободен'), ('busy', 'Занят')], default='free', max_length=20)),
('created', models.DateTimeField(default=django.utils.timezone.now)),
('cro', models.BooleanField(default=False)),
('date_joined', models.DateTimeField(default=django.utils.timezone.now)),
('date_of_birth', models.DateTimeField(blank=True, null=True)),
('email', models.EmailField(db_index=True, max_length=255, unique=True)),
('first_name', models.CharField(blank=True, max_length=255)),
('gender', models.CharField(blank=True, choices=[('male', 'Мужской'), ('female', 'Женский')], max_length=30)),
('is_active', models.BooleanField(default=True)),
('last_name', models.CharField(blank=True, max_length=255)),
('last_time_visit', models.DateTimeField(default=django.utils.timezone.now)),
('patronym', models.CharField(blank=True, max_length=255)),
('phone', models.CharField(blank=True, max_length=30, null=True)),
('skype', models.CharField(blank=True, max_length=100)),
('username', models.CharField(max_length=50, unique=True)),
('website', models.CharField(blank=True, max_length=255)),
],
options={
'verbose_name': 'Пользователь',
'verbose_name_plural': 'Пользователи',
},
),
migrations.CreateModel(
name='ContractorFinancialInfo',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('credit_card_number', models.CharField(max_length=50)),
('date_of_birth', models.DateTimeField()),
('fio', models.CharField(max_length=255)),
('inn', models.CharField(max_length=100)),
('legal_status', models.CharField(choices=[('individual', 'Физическое лицо'), ('legal_entity', 'ИП и юридическое лицо')], max_length=30)),
('passport_issue_date', models.DateTimeField()),
('passport_issued_by', models.CharField(max_length=255)),
('passport_number', models.CharField(max_length=10)),
('passport_scan', models.ImageField(upload_to='users/contractors/')),
('passport_series', models.CharField(max_length=6)),
('phone', models.CharField(max_length=30)),
('residency', models.CharField(choices=[('russian_resident', 'Резидент РФ'), ('non_russian_resident', 'Нерезидент РФ'), ('refugee', 'Беженец'), ('russian_stay_permit', 'Вид на жительство')], max_length=50)),
('subdivision_code', models.CharField(max_length=10)),
('yandex_money', models.CharField(max_length=50)),
],
options={
'verbose_name': 'Финансовая информация',
'verbose_name_plural': 'Финансовая информация',
},
),
migrations.CreateModel(
name='ContractorResume',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('resume_file', models.FileField(upload_to='users/resume/files/')),
('text', models.TextField()),
],
options={
'verbose_name': 'Резюме',
'verbose_name_plural': 'Резюме',
},
),
migrations.CreateModel(
name='ContractorResumeFiles',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('description', models.TextField(blank=True)),
('img', models.ImageField(upload_to='users/resume/images/')),
('title', models.CharField(max_length=255)),
('type', models.CharField(choices=[('diplom', 'Дипломы/Сертификаты'), ('cro', 'Допуск CPO')], max_length=50)),
('resume', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='resume_files', to='users.ContractorResume')),
],
options={
'verbose_name': 'Файлы резюме',
'verbose_name_plural': 'Файлы резюме',
},
),
migrations.CreateModel(
name='Team',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(default=django.utils.timezone.now)),
('name', models.CharField(max_length=255)),
('owner', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='team', to=settings.AUTH_USER_MODEL)),
('specializations', mptt.fields.TreeManyToManyField(blank=True, related_name='teams', to='specializations.Specialization')),
('users', models.ManyToManyField(blank=True, related_name='teams', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'Команда',
'verbose_name_plural': 'Команды',
},
),
migrations.AddField(
model_name='user',
name='contractor_financial_info',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='contractor', to='users.ContractorFinancialInfo'),
),
migrations.AddField(
model_name='user',
name='contractor_resume',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='contractor', to='users.ContractorResume'),
),
migrations.AddField(
model_name='user',
name='contractor_specializations',
field=mptt.fields.TreeManyToManyField(blank=True, related_name='contractors', to='specializations.Specialization'),
),
migrations.AddField(
model_name='user',
name='groups',
field=models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups'),
),
migrations.AddField(
model_name='user',
name='location',
field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='users', to='common.Location'),
),
migrations.AddField(
model_name='user',
name='user_permissions',
field=models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions'),
),
]

@ -1,10 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-05-19 10:22 # Generated by Django 1.9.7 on 2016-07-21 15:08
from __future__ import unicode_literals from __future__ import unicode_literals
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
import django.utils.timezone
import mptt.fields
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -13,6 +15,8 @@ class Migration(migrations.Migration):
dependencies = [ dependencies = [
('auth', '0007_alter_validators_add_error_messages'), ('auth', '0007_alter_validators_add_error_messages'),
('common', '0001_initial'),
('specializations', '0001_initial'),
] ]
operations = [ operations = [
@ -23,24 +27,88 @@ class Migration(migrations.Migration):
('password', models.CharField(max_length=128, verbose_name='password')), ('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('first_name', models.CharField(blank=True, max_length=255)), ('avatar', models.ImageField(blank=True, upload_to='users/avatars/')),
('last_name', models.CharField(blank=True, max_length=255)), ('contractor_status', models.CharField(choices=[('free', 'Свободен'), ('busy', 'Занят')], default='free', max_length=20)),
('created', models.DateTimeField(default=django.utils.timezone.now)),
('cro', models.BooleanField(default=False)),
('date_joined', models.DateTimeField(default=django.utils.timezone.now)),
('date_of_birth', models.DateTimeField(blank=True, null=True)),
('email', models.EmailField(db_index=True, max_length=255, unique=True)), ('email', models.EmailField(db_index=True, max_length=255, unique=True)),
('first_name', models.CharField(blank=True, max_length=255)),
('gender', models.CharField(blank=True, choices=[('male', 'Мужской'), ('female', 'Женский')], max_length=30)),
('is_active', models.BooleanField(default=True)), ('is_active', models.BooleanField(default=True)),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), ('last_name', models.CharField(blank=True, max_length=255)),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), ('last_time_visit', models.DateTimeField(default=django.utils.timezone.now)),
('patronym', models.CharField(blank=True, max_length=255)),
('phone', models.CharField(blank=True, max_length=30, null=True)),
('skype', models.CharField(blank=True, max_length=100)),
('username', models.CharField(max_length=50, unique=True)),
('website', models.CharField(blank=True, max_length=255)),
], ],
options={ options={
'verbose_name': 'Пользователь', 'verbose_name': 'Пользователь',
'verbose_name_plural': 'Пользователи', 'verbose_name_plural': 'Пользователи',
}, },
), ),
migrations.CreateModel(
name='ContractorFinancialInfo',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('credit_card_number', models.CharField(max_length=50)),
('date_of_birth', models.DateTimeField()),
('fio', models.CharField(max_length=255)),
('inn', models.CharField(max_length=100)),
('legal_status', models.CharField(choices=[('individual', 'Физическое лицо'), ('legal_entity', 'ИП и юридическое лицо')], max_length=30)),
('passport_issue_date', models.DateTimeField()),
('passport_issued_by', models.CharField(max_length=255)),
('passport_number', models.CharField(max_length=10)),
('passport_scan', models.ImageField(upload_to='users/contractors/')),
('passport_series', models.CharField(max_length=6)),
('phone', models.CharField(max_length=30)),
('residency', models.CharField(choices=[('russian_resident', 'Резидент РФ'), ('non_russian_resident', 'Нерезидент РФ'), ('refugee', 'Беженец'), ('russian_stay_permit', 'Вид на жительство')], max_length=50)),
('subdivision_code', models.CharField(max_length=10)),
('yandex_money', models.CharField(max_length=50)),
],
options={
'verbose_name': 'Финансовая информация',
'verbose_name_plural': 'Финансовая информация',
},
),
migrations.CreateModel(
name='ContractorResume',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('resume_file', models.FileField(upload_to='users/resume/files/')),
('text', models.TextField()),
],
options={
'verbose_name': 'Резюме',
'verbose_name_plural': 'Резюме',
},
),
migrations.CreateModel(
name='ContractorResumeFiles',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('description', models.TextField(blank=True)),
('img', models.ImageField(upload_to='users/resume/images/')),
('title', models.CharField(max_length=255)),
('type', models.CharField(choices=[('diplom', 'Дипломы/Сертификаты'), ('cro', 'Допуск CPO')], max_length=50)),
('resume', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='resume_files', to='users.ContractorResume')),
],
options={
'verbose_name': 'Файлы резюме',
'verbose_name_plural': 'Файлы резюме',
},
),
migrations.CreateModel( migrations.CreateModel(
name='Team', name='Team',
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(default=django.utils.timezone.now)),
('name', models.CharField(max_length=255)), ('name', models.CharField(max_length=255)),
('owner', models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='team', to=settings.AUTH_USER_MODEL)), ('owner', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='team', to=settings.AUTH_USER_MODEL)),
('specializations', mptt.fields.TreeManyToManyField(blank=True, related_name='teams', to='specializations.Specialization')),
('users', models.ManyToManyField(blank=True, related_name='teams', to=settings.AUTH_USER_MODEL)), ('users', models.ManyToManyField(blank=True, related_name='teams', to=settings.AUTH_USER_MODEL)),
], ],
options={ options={
@ -48,4 +116,34 @@ class Migration(migrations.Migration):
'verbose_name_plural': 'Команды', 'verbose_name_plural': 'Команды',
}, },
), ),
migrations.AddField(
model_name='user',
name='contractor_financial_info',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='contractor', to='users.ContractorFinancialInfo'),
),
migrations.AddField(
model_name='user',
name='contractor_resume',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='contractor', to='users.ContractorResume'),
),
migrations.AddField(
model_name='user',
name='contractor_specializations',
field=mptt.fields.TreeManyToManyField(blank=True, related_name='contractors', to='specializations.Specialization'),
),
migrations.AddField(
model_name='user',
name='groups',
field=models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups'),
),
migrations.AddField(
model_name='user',
name='location',
field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='users', to='common.Location'),
),
migrations.AddField(
model_name='user',
name='user_permissions',
field=models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions'),
),
] ]

@ -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')
@ -26,7 +25,7 @@ class UserManager(BaseUserManager):
return user return user
def create_superuser(self, username, password): def create_superuser(self, username, password):
user = self.create_user(username, "admin@exampletest.com", password) user = self.create_user(username, 'admin@exampletest.com', password)
user.is_superuser = True user.is_superuser = True
user.save(using=self._db) user.save(using=self._db)
return user return user
@ -55,20 +54,20 @@ class ContractorFinancialInfo(models.Model):
('legal_entity', 'ИП и юридическое лицо'), ('legal_entity', 'ИП и юридическое лицо'),
) )
fio = models.CharField(max_length=255) credit_card_number = models.CharField(max_length=50)
date_of_birth = models.DateTimeField() date_of_birth = models.DateTimeField()
phone = models.CharField(max_length=30) fio = models.CharField(max_length=255)
residency = models.CharField(max_length=50, choices=RESIDENCIES) inn = models.CharField(max_length=100)
legal_status = models.CharField(max_length=30, choices=LEGAL_STATUSES) legal_status = models.CharField(max_length=30, choices=LEGAL_STATUSES)
passport_series = models.CharField(max_length=6) passport_issue_date = models.DateTimeField()
passport_issued_by = models.CharField(max_length=255)
passport_number = models.CharField(max_length=10) passport_number = models.CharField(max_length=10)
passport_scan = models.ImageField(upload_to='users/contractors/')
passport_series = models.CharField(max_length=6)
phone = models.CharField(max_length=30)
residency = models.CharField(max_length=50, choices=RESIDENCIES)
subdivision_code = models.CharField(max_length=10) subdivision_code = models.CharField(max_length=10)
passport_issued_by = models.CharField(max_length=255)
passport_issue_date = models.DateTimeField()
inn = models.CharField(max_length=100)
yandex_money = models.CharField(max_length=50) yandex_money = models.CharField(max_length=50)
credit_card_number = models.CharField(max_length=50)
passport_scan = models.ImageField(upload_to='users/contractors/')
def __str__(self): def __str__(self):
return self.fio return self.fio
@ -77,9 +76,10 @@ class ContractorFinancialInfo(models.Model):
verbose_name = 'Финансовая информация' verbose_name = 'Финансовая информация'
verbose_name_plural = 'Финансовая информация' verbose_name_plural = 'Финансовая информация'
class ContractorResume(models.Model): class ContractorResume(models.Model):
text = models.TextField()
resume_file = models.FileField(upload_to='users/resume/files/') resume_file = models.FileField(upload_to='users/resume/files/')
text = models.TextField()
def __str__(self): def __str__(self):
return self.text return self.text
@ -96,11 +96,11 @@ RESUME_TYPE_FILES = (
class ContractorResumeFiles(models.Model): class ContractorResumeFiles(models.Model):
description = models.TextField(blank=True)
img = models.ImageField(upload_to='users/resume/images/') img = models.ImageField(upload_to='users/resume/images/')
resume = models.ForeignKey(ContractorResume, related_name='resume_files')
title = models.CharField(max_length=255) title = models.CharField(max_length=255)
description = models.TextField(blank=True)
type = models.CharField(max_length=50, choices=RESUME_TYPE_FILES) type = models.CharField(max_length=50, choices=RESUME_TYPE_FILES)
resume = models.ForeignKey(ContractorResume, related_name='resume_files')
def __str__(self): def __str__(self):
return self.title return self.title
@ -116,27 +116,27 @@ class User(AbstractBaseUser, PermissionsMixin):
('busy', 'Занят'), ('busy', 'Занят'),
) )
username = models.CharField(max_length=50, unique=True) avatar = models.ImageField(upload_to='users/avatars/', blank=True)
first_name = models.CharField(max_length=255, blank=True) contractor_financial_info = models.OneToOneField(ContractorFinancialInfo, related_name='contractor', blank=True, null=True)
last_name = models.CharField(max_length=255, blank=True) contractor_resume = models.OneToOneField(ContractorResume, related_name='contractor', blank=True, null=True)
patronym = models.CharField(max_length=255, blank=True) contractor_specializations = TreeManyToManyField(Specialization, related_name='contractors', blank=True)
email = models.EmailField(max_length=255, unique=True, db_index=True) contractor_status = models.CharField(default='free', max_length=20, choices=STATUSES)
is_active = models.BooleanField(default=True)
created = models.DateTimeField(default=timezone.now) created = models.DateTimeField(default=timezone.now)
cro = models.BooleanField(default=False)
date_joined = models.DateTimeField(default=timezone.now) date_joined = models.DateTimeField(default=timezone.now)
date_of_birth = models.DateTimeField(null=True, blank=True)
email = models.EmailField(max_length=255, unique=True, db_index=True)
first_name = models.CharField(max_length=255, blank=True)
gender = models.CharField(max_length=30, choices=GENDERS, blank=True)
is_active = models.BooleanField(default=True)
last_name = models.CharField(max_length=255, blank=True)
last_time_visit = models.DateTimeField(default=timezone.now) last_time_visit = models.DateTimeField(default=timezone.now)
contractor_specializations = TreeManyToManyField(Specialization, related_name='contractors', blank=True)
contractor_status = models.CharField(default='free', max_length=20, choices=STATUSES)
contractor_financial_info = models.OneToOneField(ContractorFinancialInfo, related_name='contractor',blank=True, null=True)
contractor_resume = models.OneToOneField(ContractorResume, related_name='contractor', blank=True, null=True)
location = TreeForeignKey('common.Location', related_name='users', null=True, blank=True) location = TreeForeignKey('common.Location', related_name='users', null=True, blank=True)
patronym = models.CharField(max_length=255, blank=True)
phone = models.CharField(max_length=30, blank=True, null=True)
skype = models.CharField(max_length=100, blank=True) skype = models.CharField(max_length=100, blank=True)
gender = models.CharField(max_length=30, choices=GENDERS, blank=True) username = models.CharField(max_length=50, unique=True)
cro = models.BooleanField(default=False)
website = models.CharField(max_length=255, blank=True) website = models.CharField(max_length=255, blank=True)
date_of_birth = models.DateTimeField(null=True,blank=True)
avatar = models.ImageField(upload_to='users/avatars/', blank=True)
phone = models.CharField(max_length=30, blank=True, null=True)
@property @property
def is_staff(self): def is_staff(self):
@ -176,14 +176,14 @@ class User(AbstractBaseUser, PermissionsMixin):
def is_owner_profile(self, user_id): def is_owner_profile(self, user_id):
pass pass
# return
class Team(models.Model): class Team(models.Model):
created = models.DateTimeField(default=timezone.now)
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
users = models.ManyToManyField(User, related_name ='teams', blank=True)
owner = models.OneToOneField(User, related_name='team', blank=True, null=True) owner = models.OneToOneField(User, related_name='team', blank=True, null=True)
# groups = models.ManyToManyField(Group, related_name='teams', blank=True) specializations = TreeManyToManyField(Specialization, related_name='teams', blank=True)
users = models.ManyToManyField(User, related_name ='teams', blank=True)
def __str__(self): def __str__(self):
return self.name return self.name

@ -0,0 +1,446 @@
{% extends 'partials/base.html' %}
{% load common_tags %}
{% block content %}
{% include 'partials/header.html' %}
<div class="container mainScore">
<div class="row">
<div class="col-lg-12">
<p class="titleScore">{% if display_msg %}{{ display_msg }}{% else %}Поиск исполнителей{% endif %}</p>
</div>
<form action="{% url 'users:contractor-filter' %}" method="GET" novalidate>
<div class="col-lg-12">
<div class="filter clearfix">
<div class="triangle1"></div>
<div class="titleF1 disTab">
<div class="col-lg-3">Специализации</div>
</div>
<div class="polsF1 disTab">
<div class="col-lg-3">
<input type="hidden" class="-spec-select -spec-select-level-1" style="width: 100%">
</div>
<div class="col-lg-3">
<input type="hidden" class="-spec-select -spec-select-level-2" style="width: 100%">
</div>
<div class="col-lg-3">
<input type="hidden" class="-spec-select -spec-select-level-3" style="width: 100%">
</div>
<div class="col-lg-3">
<input type="hidden" class="-spec-select -spec-select-level-4" style="width: 100%">
</div>
<input type="hidden" id="chosenSpecId" name="{{ form.specialization.html_name }}" value="{{ form.specialization.value }}">
</div>
<div class="titleF1 titleF2 disTab">
<div class="col-lg-3">Местоположение</div>
</div>
<div class="searchF1 polsF1 polsFF polsF3">
<div class="col-lg-3">
<input type="hidden" class="-location-select -location-select-country" style="width: 100%">
</div>
<div class="col-lg-3">
<input type="hidden" class="-location-select -location-select-region" style="width: 100%">
</div>
<div class="col-lg-3">
<input type="hidden" class="-location-select -location-select-city" style="width: 100%">
</div>
<input type="hidden" id="chosenLocationId" name="{{ form.location.html_name }}" value="{{ form.location.value }}">
<div class="col-lg-3">
<a href="#" class="findReal" onclick="$(this).closest('form').submit(); return false">
найти исполнителя
</a>
</div>
<div class="col-lg-3">
<a href="{% url 'users:contractor-filter' %}" class="clearSearch">
Очистить фильтр
</a>
</div>
</div>
<div class="resSearchF1">
<div class="col-lg-3">
<p class="titleResF1">Расширенный поиск</p>
<button class="resButtonF1">
<span class="glyphicon glyphicon-arrow-up" aria-hidden="true"></span>
</button>
</div>
<div class="col-lg-9">
<div class="borderS1"></div>
</div>
</div>
<div class="slideRes disTab activeSlide">
<div class="titleF1 disTab">
<div class="col-lg-3">Классификация здания</div>
<div class="col-lg-3">Тип работы</div>
<div class="col-lg-3">Вид строительства</div>
</div>
<div class="polsF1 disTab">
<div class="col-lg-3">
{{ form.building_classification }}
</div>
<div class="col-lg-3">
{{ form.work_type }}
</div>
<div class="col-lg-3">
{{ form.construction_type }}
</div>
<div class="col-lg-3">
<label>{{ form.cro }}<span></span></label>
<p>Требуется допуск (СРО)</p>
</div>
</div>
</div>
</div>
</div>
<div class="buttonGP disTab">
<div class="btn-group valProject valProject2" role="group" aria-label="...">
{% for val, text in form.party_types.field.choices %}
<button
type="submit"
name="{{ form.party_types.html_name }}"
value="{{ val }}"
class="{% if val == last_party_types %}active{% endif %} btn btn-default">
{{ text }}
</button>
{% endfor %}
</div>
<input type="hidden" name="{{ form.last_party_types.html_name }}" value="{{ last_party_types }}">
<div class="polsF1 disTab polsSearch">
<div class="col-lg-3">
<select name="{{ form.order_by.html_name }}" onchange="$(this).closest('form').submit()" class="selectpicker">
{% for val, text in form.order_by.field.choices %}
<option value="{{ val }}">{{ text }}</option>
{% endfor %}
</select>
</div>
<input type="hidden" name="{{ form.last_order_by.html_name }}" value="{{ last_order_by }}">
<input type="checkbox" name="{{ form.reverse_order.html_name }}" {% if reverse_order %}checked{% endif %} style="display: none">
</div>
</div>
{% for obj in coll %}
{% if obj|class_name == 'Team' %}
{% with team=obj %}
<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="#">{{ team.name }}</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" style="margin-bottom: 20px">#}
{# <pre><!--#}
{# --><b>######## Team owner #########</b><br><!--#}
{# --><br><!--#}
{# --><b>Specializations:</b> {{ team.owner.contractor_specializations.all }}<br><!--#}
{# --><br><!--#}
{# --><b>Location:</b> {{ team.owner.location }}<br><!--#}
{# --><br><!--#}
{# --><b>Build. classif-s:</b> {% for o in team.owner.orders.all %}{{ o.project.realty.building_classification }}, {% endfor %}<br><!--#}
{# --><br><!--#}
{# --><b>Constr. types:</b> {% for o in team.owner.orders.all %}{{ o.project.realty.construction_type }}, {% endfor %}<br><!--#}
{# --><br><!--#}
{# --><b>CRO:</b> {{ team.owner.cro }}<br><!--#}
{# --><br><!--#}
{# --><b>Work types:</b> {% for o in team.owner.orders.all %}{{ o.project.work_type }}, {% endfor %}<br><!--#}
{# --><br><!--#}
{# --><br><!--#}
{# --><br><!--#}
{# --><b>######## Team users #########</b><br><!--#}
{# --><br><!--#}
{# --><b>Specializations:</b> {% for u in team.users.all %}{{ u.contractor_specializations.all }}, {% endfor %}<br><!--#}
{# --><br><!--#}
{# --><b>Location:</b> {% for u in team.users.all %}{{ u.location }}, {% endfor %}<br><!--#}
{# --><br><!--#}
{# --><b>Build. classif-s:</b> {% for u in team.users.all %}{% for o in u.orders.all %}{{ o.project.realty.building_classification }}, {% endfor %}; {% endfor %}<br><!--#}
{# --><br><!--#}
{# --><b>Constr. types:</b> {% for u in team.users.all %}{% for o in u.orders.all %}{{ o.project.realty.construction_type }}, {% endfor %}; {% endfor %}<br><!--#}
{# --><br><!--#}
{# --><b>CRO:</b> {% for u in team.users.all %}{{ u.cro }}, {% endfor %}<br><!--#}
{# --><br><!--#}
{# --><b>Work types:</b> {% for u in team.users.all %}{% for o in u.orders.all %}{{ o.project.work_type }}, {% endfor %}; {% endfor %}<br><!--#}
{# --></pre>#}
{# </div>#}
{# {% endif %}#}
<div class="gallMini disTab">
{% for portf in team.portfolios.all|slice:':4' %}
<div class="col-lg-3">
<a href="#" class="linkInsetCol">
<div class="insetCol box-sizing disTab">
<div class="imgGal" style="background-image: url('{{ portf.photos.first.img.url }}')">
<div class="imgFigure"></div>
</div>
</div>
</a>
</div>
{% endfor %}
</div>
</div>
{% endwith %}
{% elif obj|class_name == 'User' %}
{% with contractor=obj %}
<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="{% url 'users:contractor-profile' pk=obj.pk %}">
смотреть профиль
</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">
{% for portf in contractor.portfolios.all|slice:':4' %}
<div class="col-lg-3">
<a href="#" class="linkInsetCol">
<div class="insetCol box-sizing disTab">
<div class="imgGal" style="background-image: url('{{ portf.photos.first.img.url }}')">
<div class="imgFigure"></div>
</div>
</div>
</a>
</div>
{% endfor %}
</div>
</div>
{% endwith %}
{% endif %}
{% endfor %}
<div class="col-lg-12 pagin">
{% include 'partials/pagination.html' %}
</div>
</form>
{% include 'partials/footer.html' %}
</div>
</div>
{% endblock %}

@ -1,7 +0,0 @@
{% extends 'partials/base.html' %}
{% block content %}
<h1>Исполнители</h1>
{% endblock %}

@ -141,7 +141,7 @@
<div class="col-lg-4"> <div class="col-lg-4">
<div class="insetCol box-sizing disTab"> <div class="insetCol box-sizing disTab">
<div class="imgGal" <div class="imgGal"
style="background:rgba(0, 0, 0, 0) url('/media/{{ p.get_cover }}') no-repeat scroll center center / cover ;"> style="background:rgba(0, 0, 0, 0) url('{{ p.get_cover }}') no-repeat scroll center center / cover ;">
<div class="imgFigure"></div> <div class="imgFigure"></div>
</div> </div>
</div> </div>

@ -7,7 +7,7 @@
<div class="row"> <div class="row">
{% include 'partials/customer_profile_info_block.html' %} {% include 'partials/customer_profile_info_block.html' %}
<h1>Reviews will be here</h1> <h1>{{ customer }}</h1>
{% include 'partials/footer.html' %} {% include 'partials/footer.html' %}
</div> </div>

@ -3,21 +3,21 @@ from django.conf.urls import include
from django.contrib.auth.views import login, logout from django.contrib.auth.views import login, logout
from .views import ( from .views import (
ContractorListView, # UserDetailView,
# UserInfoListView,
# UserView,
ContractorFilterView,
ContractorFinancialInfoEdit,
ContractorOfficeDetailView, ContractorOfficeDetailView,
ContractorProfileDetailView, ContractorProfileDetailView,
ContractorProfileEditView, ContractorProfileEditView,
CustomerProfileCurrentProjectsView, CustomerProfileCurrentProjectsView,
CustomerProfileEditView,
CustomerProfileOpenProjectsView, CustomerProfileOpenProjectsView,
CustomerProfileReviewsView, CustomerProfileReviewsView,
CustomerProfileTrashedProjectsView, CustomerProfileTrashedProjectsView,
ContractorFinancialInfoEdit,
CustomerProfileEditView,
# UserDetailView,
# UserInfoListView,
UserListView,
# UserView,
send_mail_test, send_mail_test,
UserListView,
) )
@ -30,13 +30,13 @@ urlpatterns = [
urls.url(r'^customers/(?P<pk>\d+)/current-projects/$', CustomerProfileCurrentProjectsView.as_view(), name='customer-profile-current-projects'), urls.url(r'^customers/(?P<pk>\d+)/current-projects/$', CustomerProfileCurrentProjectsView.as_view(), name='customer-profile-current-projects'),
urls.url(r'^customers/(?P<pk>\d+)/reviews/$', CustomerProfileReviewsView.as_view(), name='customer-profile-reviews'), urls.url(r'^customers/(?P<pk>\d+)/reviews/$', CustomerProfileReviewsView.as_view(), name='customer-profile-reviews'),
urls.url(r'contractors/$', ContractorFilterView.as_view(), name='contractor-filter'),
urls.url(r'^contractors/(?P<pk>\d+)/$', ContractorProfileDetailView.as_view(), name='contractor-profile'), urls.url(r'^contractors/(?P<pk>\d+)/$', ContractorProfileDetailView.as_view(), name='contractor-profile'),
urls.url(r'^contractor-office/(?P<pk>\d+)/$', ContractorOfficeDetailView.as_view(), name='contractor-office'), urls.url(r'^contractor-office/(?P<pk>\d+)/$', ContractorOfficeDetailView.as_view(), name='contractor-office'),
# urls.url(r'^profile/$', UserDetailView.as_view(), name='user-detail'), # urls.url(r'^profile/$', UserDetailView.as_view(), name='user-detail'),
urls.url(r'^$', UserListView.as_view(), name='users_list'), urls.url(r'^$', UserListView.as_view(), name='users_list'),
urls.url(r'^test/$', send_mail_test), urls.url(r'^test/$', send_mail_test),
# urls.url(r'^info$', UserInfoListView.as_view(), name='users_info_list'), # urls.url(r'^info$', UserInfoListView.as_view(), name='users_info_list'),
urls.url(r'contractors/$', ContractorListView.as_view(), name='contractor-list'),
# urls.url(r'^(?P<pk>\d+)/$', UserView.as_view(), name='user_view'), # urls.url(r'^(?P<pk>\d+)/$', UserView.as_view(), name='user_view'),
urls.url(r'contractors/(?P<pk>\d+)/edit/$', ContractorProfileEditView.as_view(), name='contractor-edit'), urls.url(r'contractors/(?P<pk>\d+)/edit/$', ContractorProfileEditView.as_view(), name='contractor-edit'),
urls.url(r'customers/(?P<pk>\d+)/edit/$', CustomerProfileEditView.as_view(), name='customers-edit'), urls.url(r'customers/(?P<pk>\d+)/edit/$', CustomerProfileEditView.as_view(), name='customers-edit'),

@ -1,21 +1,26 @@
from django.shortcuts import render, get_object_or_404, redirect from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.models import Group from django.contrib.auth.models import Group
from django.views.generic import ListView, DetailView, View, UpdateView, CreateView from django.core.mail import send_mail
from django.views.generic.base import TemplateView from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.db.models import Q
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, 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 specializations.models import Specialization from specializations.models import Specialization
from work_sell.forms import WorkSellForm from work_sell.forms import WorkSellForm
from projects.forms import PortfolioForm
from .models import User, ContractorFinancialInfo
from .mixins import CheckForUserMixin
from .forms import UserEditForm, ContractorFinancicalInfoForm
from django.http import HttpResponse
from django.core.mail import send_mail
def send_mail_test(request): def send_mail_test(request):
@ -29,10 +34,185 @@ class UserListView(ListView):
context_object_name = 'users' context_object_name = 'users'
class ContractorListView(ListView): class ContractorFilterView(BaseMixin, View):
model = User template_name = 'contractor_filter.html'
template_name = 'contractor_list.html' form_class = ContractorFilterForm
context_object_name = 'contractor'
def get(self, request, *args, **kwargs):
form = self.form_class(request.GET, request=request)
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
coll = []
if form.is_valid():
contractors = teams = None
contr_count = team_count = None
get_contractors = get_teams = None
ord = None
cro = form.cleaned_data.get('cro')
specialization = form.cleaned_data.get('specialization')
location = form.cleaned_data.get('location')
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')
last_party_types = form.cleaned_data.get('last_party_types')
if party_types == 'all':
get_contractors = get_teams = True
elif party_types == 'contractors':
get_contractors = True
elif party_types == 'teams':
get_teams = True
elif not party_types:
if last_party_types == 'contractors':
get_contractors = True
elif last_party_types == 'teams':
get_teams = True
else:
get_contractors = get_teams = True
if party_types:
last_party_types = party_types
context.update({'last_party_types': last_party_types})
if get_contractors:
contractors = User.contractor_objects.filter(cro=cro)
if specialization:
contractors = contractors.filter(
contractor_specializations__lft__gte=specialization.lft,
contractor_specializations__rght__lte=specialization.rght,
)
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)
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)
if get_teams:
teams = Team.objects.filter(Q(users__cro=cro) | Q(owner__cro=cro))
if specialization:
teams = teams.filter(
(
Q(users__contractor_specializations__lft__gte=specialization.lft)
& Q(users__contractor_specializations__rght__lte=specialization.rght)
) | (
Q(owner__contractor_specializations__lft__gte=specialization.lft)
& Q(owner__contractor_specializations__rght__lte=specialization.rght)
),
)
if location:
teams = teams.filter(
(
Q(users__location__lft__gte=location.lft)
& Q(users__location__rght__lte=location.rght)
) | (
Q(owner__location__lft__gte=location.lft)
& Q(owner__location__rght__lte=location.rght)
),
)
if work_type:
teams = teams.filter(
Q(users__orders__project__work_type=work_type)
| Q(owner__orders__project__work_type=work_type),
)
if build_classif:
teams = teams.filter(
Q(users__orders__project__realty__building_classification=build_classif)
| Q(owner__orders__project__realty__building_classification=build_classif),
)
if constr_type:
teams = teams.filter(
Q(users__orders__project__realty__construction_type=constr_type)
| Q(owner__orders__project__realty__construction_type=constr_type),
)
if get_contractors and get_teams:
coll = tuple(itertools.chain(contractors.distinct(), teams.distinct()))
count = len(coll)
display_msg = 'Найдено %s элементов' % count if count > 0 else 'Ничего не найдено'
elif get_contractors:
coll = contractors.distinct()
count = coll.count()
display_msg = 'Найдено %s исполнителей' % count if count > 0 else 'Ничего не найдено'
elif get_teams:
coll = teams.distinct()
count = coll.count()
display_msg = 'Найдено %s групп' % count if 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:
reverse_order = not reverse_order if order_by == last_order_by else False
ord = order_by
last_order_by = ord
elif last_order_by:
ord = last_order_by
if ord:
if ord == 'name':
coll = natsort.natsorted(coll, key=lambda obj: getattr(obj, 'username', None) or obj.name, reverse=reverse_order)
elif ord =='created':
coll = natsort.natsorted(coll, key=lambda obj: obj.created, reverse=reverse_order)
context.update({
'last_order_by': last_order_by,
'reverse_order': reverse_order,
})
else:
display_msg = 'Пожалуйста, введите корректные данные'
if form.errors:
messages.info(request, (
'<p>Произошла ошибка (form)</p>'
'<pre>{form}</pre>'
).format(form=pformat(form.errors)))
paginator = Paginator(coll, settings.PAGE_SIZE)
page = request.GET.get('page')
try:
coll = paginator.page(page)
except PageNotAnInteger:
coll = paginator.page(1)
except EmptyPage:
coll = paginator.page(paginator.num_pages)
context.update({
'form': form,
'coll': coll,
'is_paginated': True,
'page_obj': coll,
'display_msg': display_msg,
})
return render(request, self.template_name, context)
class ContractorProfileDetailView(DetailView): class ContractorProfileDetailView(DetailView):
@ -158,3 +338,6 @@ class ContractorFinancialInfoEdit(CheckForUserMixin, View):
return redirect(reverse('users:contractor-financical', kwargs={'pk': request.user.pk})) return redirect(reverse('users:contractor-financical', kwargs={'pk': request.user.pk}))
return render(request, self.template_name, {'form': form}) return render(request, self.template_name, {'form': form})
# import code; code.interact(local=dict(globals(), **locals()))

@ -20,4 +20,6 @@ class WorkSellForm(forms.ModelForm):
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['location'].queryset = Location.objects.root_nodes()[0].get_descendants()
# self.fields['location'].queryset = Location.objects.root_nodes()[0].get_descendants()
self.fields['location'].queryset = Location.objects # TODO: Tmp

@ -0,0 +1,69 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-21 15:08
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import mptt.fields
import sorl.thumbnail.fields
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('common', '0001_initial'),
('projects', '0001_initial'),
('specializations', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Picture',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('file', models.ImageField(upload_to='worksell/pictures')),
('slug', models.SlugField(blank=True)),
],
),
migrations.CreateModel(
name='WorkSell',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('budget', models.DecimalField(blank=True, decimal_places=0, default=0, max_digits=10, null=True)),
('created', models.DateTimeField(blank=True, default=django.utils.timezone.now, null=True)),
('currency', models.CharField(blank=True, choices=[('rur', 'RUR'), ('usd', 'USD'), ('eur', 'EUR')], default='rur', max_length=20, null=True)),
('description', models.TextField(blank=True)),
('img', sorl.thumbnail.fields.ImageField(blank=True, null=True, upload_to='worksell/worksell')),
('name', models.CharField(max_length=255)),
('term', models.IntegerField(blank=True, default=0, null=True)),
('term_type', models.CharField(blank=True, choices=[('project', 'За проект'), ('hour', 'За час'), ('day', 'За день'), ('month', 'За месяц')], default='hour', max_length=20, null=True)),
('building_classification', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='worksells', to='projects.BuildingClassfication')),
('construction_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='worksells', to='projects.ConstructionType')),
('contractor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='work_sell', to=settings.AUTH_USER_MODEL)),
('location', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='worksells', to='common.Location')),
('specialization', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='worksells', to='specializations.Specialization')),
],
options={
'verbose_name': 'Готовая работа',
'ordering': ['-created'],
'verbose_name_plural': 'Готовые работы',
},
),
migrations.CreateModel(
name='WorkSellPhoto',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('img', sorl.thumbnail.fields.ImageField(upload_to='worksell/worksell')),
('worksell', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='photos', to='work_sell.WorkSell')),
],
options={
'verbose_name': 'Изображение Готовая работа',
'verbose_name_plural': 'Изображения Готовые работы',
},
),
]

@ -1,8 +1,13 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-06-02 12:03 # Generated by Django 1.9.7 on 2016-07-21 15:08
from __future__ import unicode_literals from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import mptt.fields
import sorl.thumbnail.fields
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -10,16 +15,55 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('common', '0001_initial'),
('projects', '0001_initial'),
('specializations', '0001_initial'),
] ]
operations = [ operations = [
migrations.CreateModel(
name='Picture',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('file', models.ImageField(upload_to='worksell/pictures')),
('slug', models.SlugField(blank=True)),
],
),
migrations.CreateModel( migrations.CreateModel(
name='WorkSell', name='WorkSell',
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)), ('budget', models.DecimalField(blank=True, decimal_places=0, default=0, max_digits=10, null=True)),
('created', models.DateTimeField(blank=True, default=django.utils.timezone.now, null=True)),
('currency', models.CharField(blank=True, choices=[('rur', 'RUR'), ('usd', 'USD'), ('eur', 'EUR')], default='rur', max_length=20, null=True)),
('description', models.TextField(blank=True)), ('description', models.TextField(blank=True)),
('img', models.ImageField(upload_to='work_sell/work_sell')), ('img', sorl.thumbnail.fields.ImageField(blank=True, null=True, upload_to='worksell/worksell')),
('name', models.CharField(max_length=255)),
('term', models.IntegerField(blank=True, default=0, null=True)),
('term_type', models.CharField(blank=True, choices=[('project', 'За проект'), ('hour', 'За час'), ('day', 'За день'), ('month', 'За месяц')], default='hour', max_length=20, null=True)),
('building_classification', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='worksells', to='projects.BuildingClassfication')),
('construction_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='worksells', to='projects.ConstructionType')),
('contractor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='work_sell', to=settings.AUTH_USER_MODEL)),
('location', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='worksells', to='common.Location')),
('specialization', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='worksells', to='specializations.Specialization')),
],
options={
'verbose_name': 'Готовая работа',
'ordering': ['-created'],
'verbose_name_plural': 'Готовые работы',
},
),
migrations.CreateModel(
name='WorkSellPhoto',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('img', sorl.thumbnail.fields.ImageField(upload_to='worksell/worksell')),
('worksell', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='photos', to='work_sell.WorkSell')),
], ],
options={
'verbose_name': 'Изображение Готовая работа',
'verbose_name_plural': 'Изображения Готовые работы',
},
), ),
] ]

@ -10,19 +10,19 @@ from specializations.models import Specialization
class WorkSell(models.Model): class WorkSell(models.Model):
name = models.CharField(max_length=255)
description = models.TextField(blank=True)
img = ImageField(upload_to='worksell/worksell', null=True, blank=True)
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 = models.ForeignKey(BuildingClassfication, related_name='worksells', null=True, blank=True)
construction_type = models.ForeignKey(ConstructionType, related_name='worksells', null=True, blank=True)
contractor = models.ForeignKey(User, related_name='work_sell')
created = models.DateTimeField(default=timezone.now, null=True, blank=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)
img = ImageField(upload_to='worksell/worksell', null=True, blank=True)
location = TreeForeignKey('common.Location', related_name='worksells', null=True, blank=True)
name = models.CharField(max_length=255)
specialization = TreeForeignKey(Specialization, related_name='worksells', null=True, blank=True) specialization = TreeForeignKey(Specialization, related_name='worksells', 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=TERMS, default='hour', null=True, blank=True) term_type = models.CharField(max_length=20, choices=TERMS, default='hour', null=True, blank=True)
contractor = models.ForeignKey(User, related_name='work_sell')
building_classification = models.ForeignKey(BuildingClassfication, related_name='worksells', null=True, blank=True)
construction_type = models.ForeignKey(ConstructionType, related_name='worksells', null=True, blank=True)
location = TreeForeignKey('common.Location', related_name='worksells', null=True, blank=True)
created = models.DateTimeField(default=timezone.now, null=True, blank=True)
def __str__(self): def __str__(self):
return self.name return self.name

@ -9,171 +9,183 @@
<div class="col-lg-12"> <div class="col-lg-12">
<p class="titleScore">Работы на продажу</p> <p class="titleScore">Работы на продажу</p>
</div> </div>
<form>
<div class="col-lg-12">
<div class="filter clearfix"> <form action="{{ request.path }}" method="GET" novalidate>
<div class="triangle1"></div> <div class="col-lg-12">
<div class="titleF1 disTab"> <div class="filter clearfix">
<div class="col-lg-3">Специализации:</div> <div class="triangle1"></div>
<div class="col-lg-3"></div>
<div class="col-lg-3"></div>
<div class="col-lg-3"></div>
</div>
<div class="polsF1 disTab">
<div class="col-lg-3">
<input type='hidden' class="-spec-select -spec-select-level-1" style="width: 100%">
</div>
<div class="col-lg-3">
<input type='hidden' class="-spec-select -spec-select-level-2" style="width: 100%">
</div>
<div class="col-lg-3">
<input type='hidden' class="-spec-select -spec-select-level-3" style="width: 100%">
</div>
<div class="col-lg-3">
<input type='hidden' class="-spec-select -spec-select-level-4" style="width: 100%">
</div>
</div>
<div class="titleF1 titleF2 disTab">
<div class="col-lg-4">Тип работ:</div>
<div class="col-lg-8"></div>
</div>
<div class="searchF1 polsF1 polsFF">
<div class="col-lg-4">
<input type="text" placeholder="От" name="from_budget" class="box-sizing otInp">
<input type="text" placeholder="До" name="to_budget" class="box-sizing otInp">
<select class="selectpicker2 valul">
<option>&#36;</option>
<option>&#36;</option>
<option>&#36;</option>
</select>
</div>
<div class="col-lg-3">
</div>
<div class="col-lg-3">
<button type="submit" class="findReal">Поиск</button>
</div>
<div class="col-lg-2">
<a href="javascript:void(0)" class="clearSearch">
Очистить фильтр
</a>
</div>
</div>
<div class="resSearchF1">
<div class="col-lg-3">
<p class="titleResF1">Расширенный поиск</p>
<button class="resButtonF1">
<span class="glyphicon glyphicon-arrow-up" aria-hidden="true"></span>
</button>
</div>
<div class="col-lg-9">
<div class="borderS1"></div>
</div>
</div>
<div class="slideRes disTab activeSlide">
<div class="titleF1 disTab"> <div class="titleF1 disTab">
<div class="col-lg-3">Классификация</div> <div class="col-lg-3">Специализации:</div>
<div class="col-lg-3">Вид строительства:</div> <div class="col-lg-3"></div>
<div class="col-lg-3">Местоположение:</div> <div class="col-lg-3"></div>
<div class="col-lg-3"></div> <div class="col-lg-3"></div>
</div> </div>
<div class="polsF1 polsF2 disTab"> <div class="polsF1 disTab">
<div class="col-lg-3"> <div class="col-lg-3">
<select class="selectpicker" name="building_classification"> <input type='hidden' class="-spec-select -spec-select-level-1" style="width: 100%">
{% for bc in building_classifications %}
<option>{{ bc }}</option>
{% endfor %}
</select>
</div> </div>
<div class="col-lg-3"> <div class="col-lg-3">
<select class="selectpicker"> <input type='hidden' class="-spec-select -spec-select-level-2" style="width: 100%">
{% for ct in construction_types %}
<option>{{ ct }}</option>
{% endfor %}
</select>
</div> </div>
<div class="col-lg-3"> <div class="col-lg-3">
<select class="selectpicker"> <input type='hidden' class="-spec-select -spec-select-level-3" style="width: 100%">
<option>Mustard</option>
</select>
</div> </div>
<div class="col-lg-3"> <div class="col-lg-3">
<select class="selectpicker"> <input type='hidden' class="-spec-select -spec-select-level-4" style="width: 100%">
<option>Mustard</option> </div>
</div>
<div class="titleF1 titleF2 disTab">
<div class="col-lg-4">Тип работ:</div>
<div class="col-lg-8"></div>
</div>
<div class="searchF1 polsF1 polsFF">
<div class="col-lg-4">
<input type="text" placeholder="От" name="from_budget" class="box-sizing otInp">
<input type="text" placeholder="До" name="to_budget" class="box-sizing otInp">
<select class="selectpicker2 valul">
<option>&#36;</option>
<option>&#36;</option>
<option>&#36;</option>
</select> </select>
</div> </div>
<div class="col-lg-3">
</div>
<div class="col-lg-3">
<button type="submit" class="findReal">Поиск</button>
</div>
<div class="col-lg-2">
<a href="javascript:void(0)" class="clearSearch">
Очистить фильтр
</a>
</div>
</div>
<div class="resSearchF1">
<div class="col-lg-3">
<p class="titleResF1">Расширенный поиск</p>
<button class="resButtonF1">
<span class="glyphicon glyphicon-arrow-up" aria-hidden="true"></span>
</button>
</div>
<div class="col-lg-9">
<div class="borderS1"></div>
</div>
</div>
<div class="slideRes disTab activeSlide">
<div class="titleF1 disTab">
<div class="col-lg-3">Классификация</div>
<div class="col-lg-3">Вид строительства:</div>
<div class="col-lg-3">Местоположение:</div>
<div class="col-lg-3"></div>
</div>
<div class="polsF1 polsF2 disTab">
<div class="col-lg-3">
<select class="selectpicker" name="building_classification">
{% for bc in building_classifications %}
<option>{{ bc }}</option>
{% endfor %}
</select>
</div>
<div class="col-lg-3">
<select class="selectpicker">
{% for ct in construction_types %}
<option>{{ ct }}</option>
{% endfor %}
</select>
</div>
<div class="col-lg-3">
<select class="selectpicker">
<option>Mustard</option>
</select>
</div>
<div class="col-lg-3">
<select class="selectpicker">
<option>Mustard</option>
</select>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div>
</form> <div class="galleryWork disTab">
<div class="galleryWork disTab"> {% for work in object_list %}
{% for work in object_list %} <div class="col-lg-3">
<div class="col-lg-3"> <div class="insetCol box-sizing disTab">
<div class="insetCol box-sizing disTab"> <a href="{% url 'work_sell:detail' work.pk %}">
<a href="{% url 'work_sell:detail' work.pk %}"> {% thumbnail work.img "265x265" crop="center" as im %}
{% thumbnail work.img "265x265" crop="center" as im %} <div class="imgGal" style="background: url('{{ im.url }}') no-repeat center;">
<div class="imgGal" style="background: url('{{ im.url }}') no-repeat center;"> <div class="imgFigure"></div>
<div class="imgFigure"></div> </div>
{% endthumbnail %}
</a>
<div class="cenaImg box-sizing">
<div class="cenaImgInset">
{{ work.budget }} <i class="fa fa-rub"></i>
</div> </div>
{% endthumbnail %}
</a>
<div class="cenaImg box-sizing">
<div class="cenaImgInset">
{{ work.budget }} <i class="fa fa-rub"></i>
</div> </div>
</div> </div>
</div> <div class="insetCol2 box-sizing disTab">
<div class="insetCol2 box-sizing disTab"> <p>{{ work }}</p>
<p>{{ work }}</p>
<div class="buttonsImg" disTab>
<div class="buttonsImg" disTab> <a href="{% url 'work_sell:edit' work.pk %}">
<a href="{% url 'work_sell:edit' work.pk %}"> <div class="insetBI insetBI1">
<div class="insetBI insetBI1"> <i class="fa fa-pencil"></i>
<i class="fa fa-pencil"></i> </div>
</div> </a>
</a> <a href="{% url 'work_sell:delete' work.pk %}">
<a href="{% url 'work_sell:delete' work.pk %}"> <div class="insetBI insetBI2">
<div class="insetBI insetBI2"> <i class="fa fa-times"></i>
<i class="fa fa-times"></i> </div>
</a>
</div> </div>
</a>
</div> </div>
</div> </div>
</div> {% endfor %}
{% endfor %} </div>
</div>
{% if is_paginated %}
{# {% if is_paginated %}#}
{# <div class="col-lg-12 pagin">#}
{# <nav>#}
{# <ul class="pagination">#}
{# {% if page_obj.has_previous %}#}
{# <li>#}
{# <a href="?page={{ page_obj.previous_page_number }}" aria-label="Previous">#}
{# <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>#}
{# </a>#}
{# </li>#}
{# {% endif %}#}
{# {% for page_number in paginator.page_range %}#}
{# {% if page_number == page_obj.number %}#}
{# <li class="active"><a href="#">{{ page_number }}</a></li>#}
{# {% else %}#}
{# <li><a href="?page={{ page_number }}">{{ page_number }}</a></li>#}
{# {% endif %}#}
{# {% endfor %}#}
{# #}
{# {% if page_obj.has_next %}#}
{# <li>#}
{# <a href="?page={{ page_obj.next_page_number }}" aria-label="Next">#}
{# <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>#}
{# </a>#}
{# </li>#}
{# {% endif %}#}
{# </ul>#}
{# </nav>#}
{# </div>#}
{# {% endif %}#}
<div class="col-lg-12 pagin"> <div class="col-lg-12 pagin">
<nav> {% include 'partials/pagination.html' %}
<ul class="pagination">
{% if page_obj.has_previous %}
<li>
<a href="?page={{ page_obj.previous_page_number }}" aria-label="Previous">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
</a>
</li>
{% endif %}
{% for page_number in paginator.page_range %}
{% if page_number == page_obj.number %}
<li class="active"><a href="#">{{ page_number }}</a></li>
{% else %}
<li><a href="?page={{ page_number }}">{{ page_number }}</a></li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li>
<a href="?page={{ page_obj.next_page_number }}" aria-label="Next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
</a>
</li>
{% endif %}
</ul>
</nav>
</div> </div>
{% endif %} </form>
{% include 'partials/footer.html' %} {% include 'partials/footer.html' %}
</div> </div>

Loading…
Cancel
Save