From 457374235518ca209471d8aeb11dfc855b77a919 Mon Sep 17 00:00:00 2001 From: Mukhtar Date: Fri, 3 Jun 2016 19:02:50 +0300 Subject: [PATCH] add contractor and customer profile --- archilance/settings/base.py | 2 +- .../migrations/0016_auto_20160603_1140.py | 26 + projects/models.py | 4 +- projects/templates/projects/comparison.html | 66 +++ .../templates/projects/project_detail.html | 490 +++++++++--------- projects/urls.py | 5 +- projects/utils.py | 8 + projects/views.py | 35 +- templates/base.html | 7 +- templates/base2.html | 15 +- users/migrations/0010_user_last_time_visit.py | 21 + users/models.py | 8 + users/templates/users/contractor.html | 2 +- users/templates/users/contractor_list.html | 7 + users/templates/users/customer.html | 136 ++++- users/urls.py | 10 +- users/views.py | 22 +- 17 files changed, 582 insertions(+), 282 deletions(-) create mode 100644 projects/migrations/0016_auto_20160603_1140.py create mode 100644 projects/templates/projects/comparison.html create mode 100644 projects/utils.py create mode 100644 users/migrations/0010_user_last_time_visit.py create mode 100644 users/templates/users/contractor_list.html diff --git a/archilance/settings/base.py b/archilance/settings/base.py index 376ea03..3358d28 100644 --- a/archilance/settings/base.py +++ b/archilance/settings/base.py @@ -123,7 +123,7 @@ AUTHENTICATION_BACKENDS = ( LANGUAGE_CODE = 'ru-ru' -TIME_ZONE = 'UTC' +TIME_ZONE = 'Europe/Moscow' USE_I18N = True diff --git a/projects/migrations/0016_auto_20160603_1140.py b/projects/migrations/0016_auto_20160603_1140.py new file mode 100644 index 0000000..a451cb6 --- /dev/null +++ b/projects/migrations/0016_auto_20160603_1140.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.6 on 2016-06-03 11:40 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0015_auto_20160602_1606'), + ] + + operations = [ + migrations.RemoveField( + model_name='candidate', + name='user', + ), + migrations.AddField( + model_name='candidate', + name='answer', + field=models.ForeignKey(default='', on_delete=django.db.models.deletion.CASCADE, related_name='candidates', to='projects.Answer'), + preserve_default=False, + ), + ] diff --git a/projects/models.py b/projects/models.py index 5b2ca32..b188e65 100644 --- a/projects/models.py +++ b/projects/models.py @@ -103,12 +103,12 @@ class Answer(models.Model): class Candidate(models.Model): - user = models.ForeignKey(User, related_name='candidates') + answer = models.ForeignKey(Answer, related_name='candidates') project = models.ForeignKey(Project, related_name='candidates') status = models.BooleanField(default=False) def __str__(self): - pass + return self.user.get_full_name() class Meta: verbose_name = 'Кандидат' diff --git a/projects/templates/projects/comparison.html b/projects/templates/projects/comparison.html new file mode 100644 index 0000000..ca8ca0c --- /dev/null +++ b/projects/templates/projects/comparison.html @@ -0,0 +1,66 @@ +{% extends "base.html" %} +{% load staticfiles %} +{% block content %} +
+

Сравнение кандидатов по проекту

+
+
+
+

{{ object }}

+ + + + + + + + + + + + {% for cand in object.candidates.all %} + + + + + + + + + + + + {% endfor %} + +
КандидатЦенаСрокОписаниеРейтинги/отзывыБезопасные сделкиРешение
1 + + {{ cand.answer.user.get_full_name }} + {{ cand.answer.cost }} + {{ cand.answer.term }}
недели +
+ + +
    +
  • 23 560
  • +
  • + +385 + 0 + - 0 +
  • +
  • + СРО +
  • +
+
+ 5
+ Готов работать по безопасной сделке +
+
+
+
+
+
+
+
+
+{% endblock %} diff --git a/projects/templates/projects/project_detail.html b/projects/templates/projects/project_detail.html index 5bce86c..22cb98b 100644 --- a/projects/templates/projects/project_detail.html +++ b/projects/templates/projects/project_detail.html @@ -1,286 +1,290 @@ {% extends "base.html" %} - +{% load staticfiles %} {% block content %} - {% load humanize %} + {% load humanize %} {% load l10n %} -
-

{{ object }}

-
-
-
-
-

{{ object.price | intcomma }}

+
+

{{ object }}

-
- -
- execitor-image -
-
+
+
+ {% if user.is_contractor %} +
+

{{ object.price | intcomma }}

+
+ {% endif %} -

- {{ object.user.get_full_name }}[ivanov_petr] -

- -
-
- -
-
-
-

- Специализации: +

+ +
+ execitor-image +
+
+ +

+ {{ object.user.get_full_name }}[ivanov_petr]

-
- {{ object.specialization }} + +
+
+ +
+
+
+

+ Специализации: +

+
+ {{ object.specialization }} +
-
-
-
    -
  • - {{ object.created }} -
  • -
  • - {{ object.type_work }} -
  • -
- {% if object.secure_transaction %} -
-
+
+
    +
  • + {{ object.created }} +
  • +
  • + {{ object.type_work }} +
  • +
+ {% if object.secure_transaction %} +
+
-

Есть допуск СРО

+

Есть допуск СРО

+
+ {% endif %}
- {% endif %}
-
-
-
-
-
    -
  • - Местоположение: {{ object.realty.country }},{{ object.realty.city }} -
  • -
  • - Классификация здания: {{ object.realty.building_classification }} -
  • -
  • - Вид строительства: {{ object.realty.type_construction }} -
  • -
-
-
-

- {{ object.text }} -

-
-
- - Ответить на проект - -
-
- +
+
+
+
    +
  • + Местоположение: {{ object.realty.country }},{{ object.realty.city }} +
  • +
  • + Классификация здания: {{ object.realty.building_classification }} +
  • +
  • + Вид строительства: {{ object.realty.type_construction }} +
  • +
+
+
+

+ {{ object.text }} +

+
+
+ + Ответить на проект + +
+
+ +
-
- - {% if perms.projects.add_answer %} -
- {{ form.errors }} - {% csrf_token %} -
+ {% if perms.projects.add_answer %} + + {{ form.errors }} + {% csrf_token %} +
-
-
-

{{ form.cost.label }}

- +
+
+

Стоимость

+ +
-
-
-
-

{{ form.cost_type.label }}

- {{ form.cost_type }} +
+
+

Бюджет

+ {{ form.cost_type }} +
+ +
+
+
+
+

Срок

+ -
-
-
-
-
-

{{ form.term.label }}

- +
+
+
+
+

Тип срока

+ {{ form.term_type }} +
-
-
-
-

{{ form.term_type.label }}

- {{ form.term_type }} +
+
+
+
+
+

Текст

+ {{ form.project }} +
+
+
+
+
-
-
-
-
-
-

{{ form.text.label }}

- {{ form.project }} -
-
-
-
-
-
-
+ + {% endif %} - - {% endif %} +
-
- {% if not perms.projects.add_answer %} -
-
-

Исполнители

-
-
-
- - - -
-
-
-
-
-

Сравнить кандидатов

-
-
+ {% if user.is_customer %} +
+
+

Исполнители

+
+
+
+ + + +
+
+
+ +
+
+

Сравнить кандидатов

+
+
+
{% endif %} -
- {% for answer in object.answers.all %} +
+ {% for answer in object.answers.all %}
-
- -
- execitor-image -
-
-

- {{ answer.user.get_full_name }} -

- -
-
- -
-
-

Есть допуск СРО

-
-
-
-

Цена: {{ answer.cost| intcomma }} - -

-

- Срок: {{ answer.term }} {{ answer.term_type }} -

-

Опубликован: {{ answer.created }}

-
- -
-
-
-

- Иванов Петр Иванович +

+ {{ answer.user.get_full_name }}

- 13.0.2016 / 21:05 -
- - - - - + +
+
+ +
+
+

Есть допуск СРО

-

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin - gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar tempor. - Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam - fermentum, nulla luctus pharetra vulputate, felis tellus mollis orci, sed rhoncus sapien nunc - eget odio. +

+
+

Цена: {{ answer.cost| intcomma }} + +

+

+ Срок: {{ answer.term }} {{ answer.term_type }}

+

Опубликован: {{ answer.created }}

+
+
+ {% if user.is_customer %} + Кандидат + предложить проект + {% endif %} + отказ +
+
+
+
+

+ Иванов Петр Иванович +

+ 13.0.2016 / 21:05 +
+ + + + + +
+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum + laoreet. +

+
+
-
-
- {% endfor %} + {% endfor %} -
-
- -
+
+
+ +
{% endblock %} diff --git a/projects/urls.py b/projects/urls.py index a8187c5..8622c5e 100644 --- a/projects/urls.py +++ b/projects/urls.py @@ -3,13 +3,14 @@ from django.views.generic import TemplateView from .views import ProjectListView, ProjectDetailView, \ ProjectCreateView, PortfolioCreateView,\ - TestProjectView, manage_articles, TestView + ProjectComparisonView, add_candidate, TestView app_name = 'projects' urlpatterns = [ urls.url(r'^$', ProjectListView.as_view(), name='list'), - urls.url(r'^porttest/$', manage_articles, name='portfolio'), + urls.url(r'^candidate/add/(?P(\d+))/(?P(\d+))/$', add_candidate, name='add-candidate'), + urls.url(r'^candidate/comparison/(?P\d+)$', ProjectComparisonView.as_view(), name='comparison'), urls.url(r'^create/$', ProjectCreateView.as_view(), name='project-create'), urls.url(r'^test/$', TestView.as_view(), name='project-test'), urls.url(r'^portfolio/create/$', PortfolioCreateView.as_view(), name='portfolio-create'), diff --git a/projects/utils.py b/projects/utils.py new file mode 100644 index 0000000..fa72493 --- /dev/null +++ b/projects/utils.py @@ -0,0 +1,8 @@ +from django.utils import timezone + +class LastAccessMixin(object): + def dispatch(self, request, *args, **kwargs): + if request.user.is_authenticated(): + request.user.last_time_visit = timezone.now() + request.user.save(update_fields=['last_time_visit']) + return super().dispatch(request, *args, **kwargs) diff --git a/projects/views.py b/projects/views.py index c84e5a3..a97e22b 100644 --- a/projects/views.py +++ b/projects/views.py @@ -1,11 +1,15 @@ -from django.http import HttpResponseForbidden, HttpResponseRedirect +from django.shortcuts import render +from django.http import HttpResponseForbidden, HttpResponseRedirect, HttpResponse from django.core.urlresolvers import reverse from django.contrib.auth.mixins import PermissionRequiredMixin from django.views.generic import ListView, DetailView, CreateView, View, TemplateView from django.views.generic.edit import FormMixin -from .models import Project, Portfolio + +from users.models import User +from .models import Project, Portfolio, Candidate, Answer from .forms import ProjectForm, PortfolioForm, AnswerForm, RealtyForm +from .utils import LastAccessMixin class ProjectListView(ListView): @@ -17,7 +21,7 @@ class ProjectListView(ListView): return context -class ProjectDetailView(FormMixin, DetailView): +class ProjectDetailView(LastAccessMixin, FormMixin, DetailView): model = Project form_class = AnswerForm @@ -164,16 +168,21 @@ class TestProjectView(View): self.get_context_data(form=form, realty_form=realty_form)) -from django.shortcuts import render -from .forms import PortfolioPhotoFormSet -def manage_articles(request): - form = PortfolioForm - portfolio_photo_form = PortfolioPhotoFormSet() - if request.method == "POST": - form = PortfolioForm(request.POST) - portfolio_photo_form = PortfolioPhotoFormSet(request.POST, request.FILES) - import code; code.interact(local=dict(globals(), **locals())) + +class ProjectComparisonView(DetailView): + model = Project + template_name = 'projects/comparison.html' + + def get_context_data(self, **kwargs): + context = super().get_context_data() + return context + + - return render(request, 'projects/testport.html', {'form': form, 'portfolio_photo_form': portfolio_photo_form}) +def add_candidate(request, answer_id, project_id): + answer = Answer.objects.get(pk=answer_id) + project = Project.objects.get(pk=project_id) + candidate = Candidate.objects.create(answer=answer, project=project) + return HttpResponseRedirect(reverse('projects:detail',args=[project_id])) diff --git a/templates/base.html b/templates/base.html index 4e9f7a4..b0113dc 100644 --- a/templates/base.html +++ b/templates/base.html @@ -29,8 +29,13 @@
  • Биржа проектов
  • +
  • - Мой офис + {% if user.is_contractor %} + Мой офис + {% elif user.is_customer %} + Мой офис + {% endif %}
  • diff --git a/templates/base2.html b/templates/base2.html index 6b8a4bd..27dbb1f 100644 --- a/templates/base2.html +++ b/templates/base2.html @@ -28,11 +28,18 @@ Биржа проектов
  • - Поиск исполнителей -
  • -
  • - Работы на продажу + Поиск исполнителей
  • +
  • + {% if user.is_contractor %} + Мой офис + {% elif user.is_customer %} + Мой офис + {% endif %} +
  • +{#
  • #} +{# Работы на продажу#} +{#
  • #}
    diff --git a/users/migrations/0010_user_last_time_visit.py b/users/migrations/0010_user_last_time_visit.py new file mode 100644 index 0000000..9932460 --- /dev/null +++ b/users/migrations/0010_user_last_time_visit.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.6 on 2016-06-03 12:15 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0009_auto_20160602_1213'), + ] + + operations = [ + migrations.AddField( + model_name='user', + name='last_time_visit', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + ] diff --git a/users/models.py b/users/models.py index f6fe5ea..7ac0f87 100644 --- a/users/models.py +++ b/users/models.py @@ -38,6 +38,7 @@ class User(AbstractBaseUser, PermissionsMixin): 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) @property def is_staff(self): @@ -62,6 +63,13 @@ class User(AbstractBaseUser, PermissionsMixin): verbose_name = 'Пользователь' verbose_name_plural = 'Пользователи' + def is_contractor(self): + return self.groups.filter(name='Исполнители').exists() + + def is_customer(self): + return self.groups.filter(name='Заказчики').exists() + + class Team(models.Model): name = models.CharField(max_length=255) diff --git a/users/templates/users/contractor.html b/users/templates/users/contractor.html index 166f23b..1a8e17a 100644 --- a/users/templates/users/contractor.html +++ b/users/templates/users/contractor.html @@ -52,7 +52,7 @@

    Россия, Москва

    Свободен
    - показать контакты + показать контакты
    diff --git a/users/templates/users/contractor_list.html b/users/templates/users/contractor_list.html new file mode 100644 index 0000000..9b073eb --- /dev/null +++ b/users/templates/users/contractor_list.html @@ -0,0 +1,7 @@ +{% extends "base.html" %} + + +{% block content %} +

    Исполнители

    + +{% endblock %} diff --git a/users/templates/users/customer.html b/users/templates/users/customer.html index 4f080b2..f58bcf1 100644 --- a/users/templates/users/customer.html +++ b/users/templates/users/customer.html @@ -1,4 +1,138 @@ {% extends 'base.html' %} {% block content %} -

    Заказчик

    +
    +
    +
    +
    + profile-image +
    +
    +
    +
    +
    +

    + {{ object.get_full_name }} [ivanov_petr] +

    +

    Россия, Москва

    + +
    + + +
    +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    + +
    +
    +
    +

    Разместить заказ

    +
    +
    +
    + {% for proj in object.projects.all %} +
    +
    +

    + {{ proj.name }} +

    +
      +
    • + Объект "{{ proj.realty.name }}" +
    • +
    • + 0 ответ от имени группы +
    • +
    + +

    + {{ proj.text }} +

    +
      +
    • {{ proj.created}}
    • +
    • 0
    • +
    • 0
    • +
    • {{ object.get_full_name }}
    • +
    +
    +
    +

    + {{ proj.price }} +

    +
      +
    • + Редактировать +
    • +
    • + Переместить в корзину +
    • +
    +
    +
    + {% endfor %} +
    {% endblock %} diff --git a/users/urls.py b/users/urls.py index 21be00a..87fc239 100755 --- a/users/urls.py +++ b/users/urls.py @@ -1,16 +1,16 @@ from django.conf import urls from django.contrib.auth.views import login, logout -from .views import UserListView, UserDetailView, UserInfoListView, CustomerView, UserView, ContractorDetailView +from .views import UserListView, UserDetailView, UserInfoListView, CustomerView,\ + UserView, ContractorDetailView, ContractorListView app_name = 'users' urlpatterns = [ urls.url(r'^profile/$', UserDetailView.as_view(), name='user-detail'), - # urls.url(r'^login/?$', login, {'template_name': 'users/login.html'}), - # urls.url(r'^logout/?$', logout), urls.url(r'^$', UserListView.as_view(), name='users_list'), urls.url(r'^info$', UserInfoListView.as_view(), name='users_info_list'), - urls.url(r'^contractor/(?P\d+)$$', ContractorDetailView.as_view(), name='contactor_view'), - urls.url(r'^customer/(?P\d+)$$', CustomerView.as_view(), name='customer_view'), + urls.url(r'contractors/$', ContractorListView.as_view(), name='contractor-list' ), + urls.url(r'^contractor/(?P\d+)$', ContractorDetailView.as_view(), name='contractor-view'), + urls.url(r'^customer/(?P\d+)$', CustomerView.as_view(), name='customer-view'), urls.url(r'^(?P\d+)$', UserView.as_view(), name='user_view'), ] diff --git a/users/views.py b/users/views.py index 0430440..41ec904 100644 --- a/users/views.py +++ b/users/views.py @@ -46,22 +46,26 @@ class UserUpdateView(UpdateView): from django.http import Http404 from django.shortcuts import redirect + +class ContractorListView(ListView): + model = User + template_name = 'users/contractor_list.html' + class ContractorDetailView(DetailView): model = User template_name = 'users/contractor.html' - def get_object(self, queryset=None): - object = super().get_object() - user_group = object.groups.all().first() - if 'Исполнители' not in user_group.name: - return redirect('/projects/') - return object + # def get_object(self, queryset=None): + # object = super().get_object() + # user_group = object.groups.all().first() + # if 'Исполнители' not in user_group.name: + # return redirect('/projects/') + # return object -class CustomerView(View): +class CustomerView(DetailView): + model = User template_name = 'users/customer.html' - def get(self, request, *args, **kwargs): - return render(request, self.template_name)