diff --git a/archilance/settings/base.py b/archilance/settings/base.py
index 8ccb3a2..c2e290d 100644
--- a/archilance/settings/base.py
+++ b/archilance/settings/base.py
@@ -38,6 +38,7 @@ THIRD_PARTY_APPS = [
LOCAL_APPS = [
'api',
+ 'common',
'archilance',
'projects',
'specializations',
diff --git a/common/__init__.py b/common/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/common/admin.py b/common/admin.py
new file mode 100644
index 0000000..3e55e94
--- /dev/null
+++ b/common/admin.py
@@ -0,0 +1,9 @@
+from django.contrib import admin
+from mptt.admin import MPTTModelAdmin
+
+from .models import Location
+
+class LocationAdmin(MPTTModelAdmin):
+ readonly_fields = ('pk', 'lft', 'rght', 'tree_id', 'level')
+
+admin.site.register(Location, LocationAdmin)
diff --git a/common/apps.py b/common/apps.py
new file mode 100644
index 0000000..5f2f078
--- /dev/null
+++ b/common/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class CommonConfig(AppConfig):
+ name = 'common'
diff --git a/common/migrations/0001_initial.py b/common/migrations/0001_initial.py
new file mode 100644
index 0000000..7149f56
--- /dev/null
+++ b/common/migrations/0001_initial.py
@@ -0,0 +1,66 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.6 on 2016-06-15 12:56
+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='City',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=255)),
+ ],
+ options={
+ 'verbose_name_plural': 'Города',
+ 'verbose_name': 'Город',
+ },
+ ),
+ migrations.CreateModel(
+ name='Country',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=255)),
+ ],
+ options={
+ 'verbose_name_plural': 'Страны',
+ 'verbose_name': 'Страна',
+ },
+ ),
+ 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(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={
+ 'verbose_name_plural': 'Местоположения',
+ 'verbose_name': 'Местоположение',
+ },
+ 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'),
+ ),
+ ]
diff --git a/common/migrations/0002_auto_20160615_1625.py b/common/migrations/0002_auto_20160615_1625.py
new file mode 100644
index 0000000..cbdd8cd
--- /dev/null
+++ b/common/migrations/0002_auto_20160615_1625.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.6 on 2016-06-15 13:25
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('common', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='city',
+ name='country',
+ ),
+ migrations.AlterField(
+ model_name='location',
+ name='type',
+ field=models.CharField(choices=[('_root', 'Корень'), ('country', 'Страна'), ('region', 'Регион'), ('town', 'Город')], default=None, max_length=20),
+ preserve_default=False,
+ ),
+ migrations.DeleteModel(
+ name='City',
+ ),
+ migrations.DeleteModel(
+ name='Country',
+ ),
+ ]
diff --git a/common/migrations/__init__.py b/common/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/common/models.py b/common/models.py
new file mode 100644
index 0000000..e3770ed
--- /dev/null
+++ b/common/models.py
@@ -0,0 +1,21 @@
+from django.db import models
+from mptt.models import TreeForeignKey, MPTTModel
+
+class Location(MPTTModel):
+ TYPES = (
+ ('_root', 'Корень'),
+ ('country', 'Страна'),
+ ('region', 'Регион'),
+ ('town', 'Город'),
+ )
+
+ name = models.CharField(max_length=50)
+ parent = TreeForeignKey('self', blank=True, null=True, related_name='children', db_index=True)
+ type = models.CharField(max_length=20, choices=TYPES)
+
+ def __str__(self):
+ return self.name
+
+ class Meta:
+ verbose_name = 'Местоположение'
+ verbose_name_plural = 'Местоположения'
diff --git a/common/tests.py b/common/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/common/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/common/views.py b/common/views.py
new file mode 100644
index 0000000..91ea44a
--- /dev/null
+++ b/common/views.py
@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.
diff --git a/projects/admin.py b/projects/admin.py
index 7c4ac6f..a61cfe0 100644
--- a/projects/admin.py
+++ b/projects/admin.py
@@ -1,7 +1,7 @@
from django.contrib import admin
from .models import Project, Portfolio, PortfolioPhoto, \
- Answer, Realty, Candidate, Order, Stage, Country, City,\
+ Answer, Realty, Candidate, Order, Stage,\
BuildingClassfication, ConstructionType, ProjectFile
@@ -16,8 +16,6 @@ admin.site.register(Realty)
admin.site.register(Order)
admin.site.register(Candidate)
admin.site.register(Stage)
-admin.site.register(Country)
-admin.site.register(City)
admin.site.register(BuildingClassfication)
admin.site.register(ConstructionType)
admin.site.register(Project, ProjectAdmin)
diff --git a/projects/forms.py b/projects/forms.py
index e8d6dcf..46a2e51 100644
--- a/projects/forms.py
+++ b/projects/forms.py
@@ -46,8 +46,6 @@ class RealtyForm(ModelForm):
model = Realty
fields = (
- 'country',
- 'city',
'building_classification',
'construction_type',
'name',
@@ -56,8 +54,6 @@ class RealtyForm(ModelForm):
widgets = {
'construction_type': Select(attrs={'class':'selectpicker'}),
'building_classification': Select(attrs={'class':'selectpicker'}),
- 'city': Select(attrs={'class':'selectpicker'}),
- 'country': Select(attrs={'class':'selectpicker'}),
}
class Realty1Form(Form):
diff --git a/projects/migrations/0032_auto_20160615_1610.py b/projects/migrations/0032_auto_20160615_1610.py
new file mode 100644
index 0000000..30cea38
--- /dev/null
+++ b/projects/migrations/0032_auto_20160615_1610.py
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.6 on 2016-06-15 13:10
+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):
+
+ dependencies = [
+ ('common', '0001_initial'),
+ ('projects', '0031_auto_20160610_1434'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='city',
+ name='country',
+ ),
+ migrations.RemoveField(
+ model_name='realty',
+ name='city',
+ ),
+ migrations.RemoveField(
+ model_name='realty',
+ name='country',
+ ),
+ migrations.AddField(
+ model_name='realty',
+ name='location',
+ field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='realties', to='common.Location'),
+ ),
+ migrations.AlterField(
+ model_name='order',
+ name='created',
+ field=models.DateTimeField(default=django.utils.timezone.now),
+ ),
+ migrations.AlterField(
+ model_name='project',
+ name='state',
+ field=models.CharField(choices=[('active', 'Активный'), ('trashed', 'В корзине'), ('deleted', 'Удален')], default='active', max_length=20),
+ ),
+ migrations.DeleteModel(
+ name='City',
+ ),
+ migrations.DeleteModel(
+ name='Country',
+ ),
+ ]
diff --git a/projects/models.py b/projects/models.py
index 2f24027..d0be358 100644
--- a/projects/models.py
+++ b/projects/models.py
@@ -1,3 +1,4 @@
+from mptt.models import TreeForeignKey
from datetime import datetime
from django.db import models
from django.utils import timezone
@@ -40,34 +41,10 @@ class ConstructionType(models.Model):
verbose_name_plural = 'Виды строительства'
-class Country(models.Model):
- name = models.CharField(max_length=255)
-
- def __str__(self):
- return self.name
-
- class Meta:
- verbose_name = 'Страна'
- verbose_name_plural = 'Страны'
-
-
-class City(models.Model):
- name = models.CharField(max_length=255)
- country = models.ForeignKey(Country, related_name='cities')
-
- def __str__(self):
- return self.name
-
- class Meta:
- verbose_name = 'Город'
- verbose_name_plural = 'Города'
-
-
class Realty(models.Model):
building_classification = models.ForeignKey(BuildingClassfication, related_name='realties')
- city = models.ForeignKey(City, related_name='realties')
construction_type = models.ForeignKey(ConstructionType, related_name='realties')
- country = models.ForeignKey(Country, related_name='realties')
+ location = TreeForeignKey('common.Location', related_name='realties', null=True, blank=True)
name = models.CharField(max_length=255)
user = models.ForeignKey(User, related_name='realties')
diff --git a/projects/templates/_trash/project_form.html b/projects/templates/_trash/project_form.html
new file mode 100644
index 0000000..63d0ed9
--- /dev/null
+++ b/projects/templates/_trash/project_form.html
@@ -0,0 +1,278 @@
+{% extends 'partials/base.html' %}
+
+{% block content %}
+
+
+
+
+{% endblock %}
+{% block js_block %}
+
+{% endblock %}
diff --git a/projects/templates/_trash/testport.html b/projects/templates/_trash/testport.html
new file mode 100644
index 0000000..b21ecc8
--- /dev/null
+++ b/projects/templates/_trash/testport.html
@@ -0,0 +1,18 @@
+
diff --git a/projects/templates/contractor_project_detail.html b/projects/templates/contractor_project_detail.html
index 888887a..cd9c4c3 100644
--- a/projects/templates/contractor_project_detail.html
+++ b/projects/templates/contractor_project_detail.html
@@ -72,7 +72,7 @@
-
- Местоположение: {{ project.realty.country }}, {{ project.realty.city }}
+ Местоположение:
-
Классификация здания: {{ project.realty.building_classification }}
diff --git a/projects/views.py b/projects/views.py
index 815a678..27e84fa 100644
--- a/projects/views.py
+++ b/projects/views.py
@@ -26,6 +26,7 @@ from .mixins import LastAccessMixin
class ProjectsView(ListView):
model = Project
+ template_name = 'project_list.html'
class ProjectView(LastAccessMixin, View):
diff --git a/users/migrations/0014_auto_20160615_1611.py b/users/migrations/0014_auto_20160615_1611.py
new file mode 100644
index 0000000..130df78
--- /dev/null
+++ b/users/migrations/0014_auto_20160615_1611.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.6 on 2016-06-15 13:11
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+import mptt.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('common', '0001_initial'),
+ ('users', '0013_auto_20160610_1703'),
+ ]
+
+ operations = [
+ 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='patronym',
+ field=models.CharField(blank=True, max_length=255),
+ ),
+ ]
diff --git a/users/migrations/0015_auto_20160615_1747.py b/users/migrations/0015_auto_20160615_1747.py
new file mode 100644
index 0000000..26fcf13
--- /dev/null
+++ b/users/migrations/0015_auto_20160615_1747.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.6 on 2016-06-15 14:47
+from __future__ import unicode_literals
+
+import datetime
+from django.db import migrations, models
+import django.db.models.deletion
+from django.utils.timezone import utc
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('users', '0014_auto_20160615_1611'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='ContractorFinancialInfo',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('fio', models.CharField(max_length=255)),
+ ('date_of_birth', models.DateTimeField()),
+ ('phone', models.CharField(max_length=30)),
+ ('residency', models.CharField(choices=[('russian_resident', 'Резидент РФ'), ('non_russian_resident', 'Нерезидент РФ'), ('refugee', 'Беженец'), ('russian_stay_permit', 'Вид на жительство')], max_length=50)),
+ ('legal_status', models.CharField(choices=[('individual', 'Физическое лицо'), ('legal_entity', 'ИП и Юридическое лицо')], max_length=30)),
+ ('passport_series', models.CharField(max_length=6)),
+ ('passport_number', 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)),
+ ('credit_card_number', models.CharField(max_length=50)),
+ ('passport_scan', models.ImageField(upload_to='users/contractors/')),
+ ],
+ options={
+ 'verbose_name': 'Финансовая информация',
+ 'verbose_name_plural': 'Финансовая информация',
+ },
+ ),
+ migrations.AddField(
+ model_name='user',
+ name='avatar',
+ field=models.ImageField(blank=True, upload_to='users/avatars/'),
+ ),
+ migrations.AddField(
+ model_name='user',
+ name='cro',
+ field=models.BooleanField(default=False),
+ ),
+ migrations.AddField(
+ model_name='user',
+ name='date_of_birth',
+ field=models.DateTimeField(default=datetime.datetime(2016, 6, 15, 14, 47, 5, 758769, tzinfo=utc)),
+ preserve_default=False,
+ ),
+ migrations.AddField(
+ model_name='user',
+ name='gender',
+ field=models.CharField(blank=True, choices=[('male', 'Мужской'), ('female', 'Женский')], max_length=30),
+ ),
+ migrations.AddField(
+ model_name='user',
+ name='skype',
+ field=models.CharField(blank=True, max_length=100),
+ ),
+ migrations.AddField(
+ model_name='user',
+ name='website',
+ field=models.CharField(blank=True, max_length=255),
+ ),
+ 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'),
+ ),
+ ]
diff --git a/users/models.py b/users/models.py
index b8ab0ac..b76330a 100644
--- a/users/models.py
+++ b/users/models.py
@@ -1,3 +1,4 @@
+from mptt.models import TreeForeignKey
from datetime import datetime
from django.db import models
from django.utils import timezone
@@ -5,7 +6,6 @@ from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, Abstra
from specializations.models import Specialization
-
class UserManager(BaseUserManager):
def create_user(self, email, password=None):
if not email:
@@ -32,6 +32,48 @@ class CustomerUserManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(groups__name='Заказчики')
+GENDERS = (
+ ('male', 'Мужской'),
+ ('female', 'Женский'),
+)
+
+
+
+class ContractorFinancialInfo(models.Model):
+ RESIDENCIES = (
+ ('russian_resident', 'Резидент РФ'),
+ ('non_russian_resident', 'Нерезидент РФ'),
+ ('refugee', 'Беженец'),
+ ('russian_stay_permit', 'Вид на жительство'),
+ )
+
+ LEGAL_STATUSES = (
+ ('individual', 'Физическое лицо'),
+ ('legal_entity', 'ИП и Юридическое лицо'),
+ )
+
+ fio = models.CharField(max_length=255)
+ date_of_birth = models.DateTimeField()
+ phone = models.CharField(max_length=30)
+ residency = models.CharField(max_length=50,choices=RESIDENCIES)
+ legal_status = models.CharField(max_length=30, choices=LEGAL_STATUSES)
+ passport_series = models.CharField(max_length=6)
+ passport_number = 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)
+ credit_card_number = models.CharField(max_length=50)
+ passport_scan = models.ImageField(upload_to='users/contractors/')
+
+ def __str__(self):
+ return self.fio
+
+ class Meta:
+ verbose_name = 'Финансовая информация'
+ verbose_name_plural = 'Финансовая информация'
+
class User(AbstractBaseUser, PermissionsMixin):
STATUSES = (
@@ -42,13 +84,22 @@ class User(AbstractBaseUser, PermissionsMixin):
nickname = models.CharField(max_length=50, blank=True,null=True)
first_name = models.CharField(max_length=255, blank=True)
last_name = models.CharField(max_length=255, blank=True)
+ patronym = models.CharField(max_length=255, blank=True)
email = models.EmailField(max_length=255, unique=True, db_index=True)
is_active = models.BooleanField(default=True)
created = models.DateTimeField(default=timezone.now)
last_time_visit = models.DateTimeField(default=timezone.now)
contractor_specializations = models.ManyToManyField(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)
+ location = TreeForeignKey('common.Location', related_name='users', null=True, blank=True)
+ skype = models.CharField(max_length=100, blank=True)
+ gender = models.CharField(max_length=30, choices=GENDERS, blank=True)
+ cro = models.BooleanField(default=False)
+ website = models.CharField(max_length=255, blank=True)
+ date_of_birth = models.DateTimeField()
+ avatar = models.ImageField(upload_to='users/avatars/', blank=True)
+
@property
def is_staff(self):
return self.is_superuser
@@ -57,7 +108,6 @@ class User(AbstractBaseUser, PermissionsMixin):
def is_free(self):
return self.contractor_status == 'free'
-
def __str__(self):
return self.email
@@ -85,6 +135,7 @@ class User(AbstractBaseUser, PermissionsMixin):
+
class Team(models.Model):
name = models.CharField(max_length=255)
users = models.ManyToManyField(User, related_name ='teams', blank=True)
diff --git a/users/templates/contractor_profile_edit.html b/users/templates/contractor_profile_edit.html
new file mode 100644
index 0000000..7d688a3
--- /dev/null
+++ b/users/templates/contractor_profile_edit.html
@@ -0,0 +1,144 @@
+{% extends 'partials/base.html' %}
+
+{% load staticfiles %}
+
+{% block content %}
+ {% include 'partials/header.html' %}
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
Специализация:
+
+
+
+
+ Добавить еще
+
+
+
+
+
Местоположение:
+
+
+
+
+
+
+
+
+
+
+
+
+
Дата рождения:
+
Пол:
+
+
+
+
+
+
+
+
+
+
Мужской
+
+
Женский
+
+
+
+
Сайт:
+
Skype:
+
Электронная почта:
+
Телефон:
+
+
+
+
+
+
+
+ {% include 'partials/footer.html' %}
+
+
+
+
+
+
+
+{% endblock %}
diff --git a/users/templates/name_snippet.html b/users/templates/name_snippet.html
new file mode 100644
index 0000000..2e1a07c
--- /dev/null
+++ b/users/templates/name_snippet.html
@@ -0,0 +1 @@
+{{ greeting }}, {{ person|default:"friend" }}!
diff --git a/users/urls.py b/users/urls.py
index e9380ea..fcb9be9 100755
--- a/users/urls.py
+++ b/users/urls.py
@@ -5,13 +5,14 @@ from .views import (
ContractorListView,
ContractorOfficeDetailView,
ContractorProfileDetailView,
+ ContractorProfileEditView,
CustomerProfileCurrentProjectsView,
CustomerProfileOpenProjectsView,
CustomerProfileReviewsView,
CustomerProfileTrashedProjectsView,
# UserDetailView,
# UserInfoListView,
- # UserListView,
+ UserListView,
# UserView,
)
@@ -27,8 +28,9 @@ urlpatterns = [
urls.url(r'^contractors/(?P\d+)/$', ContractorProfileDetailView.as_view(), name='contractor-profile'),
urls.url(r'^contractor-office/(?P\d+)/$', ContractorOfficeDetailView.as_view(), name='contractor-office'),
# 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'^info$', UserInfoListView.as_view(), name='users_info_list'),
urls.url(r'contractors/$', ContractorListView.as_view(), name='contractor-list' ),
# urls.url(r'^(?P\d+)/$', UserView.as_view(), name='user_view'),
+ urls.url(r'contractors/(?P\d+)/edit/$', ContractorProfileEditView.as_view(), name='contractor-edit' ),
]
diff --git a/users/views.py b/users/views.py
index bd0ffd0..8b2895a 100644
--- a/users/views.py
+++ b/users/views.py
@@ -1,4 +1,4 @@
-from django.shortcuts import render
+from django.shortcuts import render, get_object_or_404
from django.contrib.auth.models import Group
from django.views.generic import ListView, DetailView, View, UpdateView
from django.views.generic.base import TemplateView
@@ -63,3 +63,11 @@ class CustomerProfileReviewsView(BaseMixin, DetailView):
model = User
template_name = 'customer_profile_reviews.html'
context_object_name = 'customer'
+
+
+class ContractorProfileEditView(BaseMixin, View):
+ template_name = 'contractor_profile_edit.html'
+
+ def get(self, request, *args, **kwargs):
+ contractor = get_object_or_404(User, pk=kwargs.get('pk'))
+ return render(request, self.template_name, {'contractor': contractor})