#ARC-4 Add projects_tags and specialization tags

remotes/origin/setup
Mukhtar 10 years ago
parent c2db336f74
commit 8be48ae531
  1. 1
      .gitignore
  2. 9
      common/utils.py
  3. 1
      projects/__init__.py
  4. 7
      projects/models.py
  5. 14
      projects/templates/templatetags/ratings_widget.html
  6. 0
      projects/templatetags/__init__.py
  7. 10
      projects/templatetags/projects_tags.py
  8. 5
      projects/views.py
  9. 1
      specializations/__init__.py
  10. 9
      specializations/templates/templatetags/specializations_widget.html
  11. 0
      specializations/templatetags/__init__.py
  12. 18
      specializations/templatetags/specializtions_tags.py
  13. 4
      templates/partials/header.html
  14. 4
      users/forms.py
  15. 4
      users/models.py
  16. 83
      users/templates/contractor_profile.html
  17. 4
      users/templates/customer_profile_current_projects.html
  18. 176
      users/templates/customer_profile_edit.html
  19. 1
      users/templates/customer_profile_open_projects.html
  20. 22
      users/templates/partials/customer_profile_info_block.html
  21. 2
      users/urls.py
  22. 27
      users/views.py
  23. 3
      work_sell/admin.py
  24. 28
      work_sell/migrations/0003_auto_20160621_1259.py
  25. 20
      work_sell/migrations/0004_worksell_price.py
  26. 7
      work_sell/models.py

1
.gitignore vendored

@ -5,3 +5,4 @@ env/
ar/
archilance/settings/local.py
media/
todo/

@ -0,0 +1,9 @@
from django.shortcuts import _get_queryset
def get_or_none(klass, *args, **kwargs):
queryset = _get_queryset(klass)
try:
return queryset.get(*args, **kwargs)
except queryset.model.DoesNotExist:
return None

@ -0,0 +1 @@
default_app_config = 'projects.apps.ProjectsConfig'

@ -188,6 +188,13 @@ class Portfolio(models.Model):
verbose_name = 'Портфолио'
verbose_name_plural = 'Портфолио'
def get_cover(self):
cover = None
all_photos = self.portfoliophoto_set.all()
if all_photos:
cover = all_photos[0].img
return cover
class PortfolioPhoto(models.Model):
img = models.ImageField(upload_to='projects/portfolio')

@ -0,0 +1,14 @@
<ul class="rettList">
<li><a href="javascript:void(0)">Рейтинг: <span> {{ ratings }}</span></a></li>
<li><a href="javascript:void(0)">Безопасные сделки: <span> 0</span></a></li>
<li>
<a href="javascript:void(0)">
Отзывы:
<span> + 0</span>
<small> 0</small>
<mark> - 0</mark>
</a>
</li>
</ul>

@ -0,0 +1,10 @@
from django import template
register = template.Library()
@register.inclusion_tag("templatetags/ratings_widget.html", takes_context=True)
def ratings_widget(context, user_id):
ratings = user_id
return {
'ratings': ratings,
}

@ -109,8 +109,9 @@ class ProjectView(BaseMixin, View):
customer_template_name = 'customer_project_detail.html'
def get(self, request, *args, **kwargs):
# import code; code.interact(local=dict(globals(), **locals()))
if request.user.is_authenticated() and request.user.is_customer():
project = get_object_or_404(request.user.projects, pk=kwargs.get('pk'))
project = get_object_or_404(Project, pk=kwargs.get('pk'))
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
context.update({'project': project})
@ -180,7 +181,6 @@ class ContractorProjectAnswerView(BaseMixin, View):
answer.project = project
answer.save()
order = Order.objects.create(project=project)
return HttpResponseRedirect(reverse('projects:detail', kwargs={'pk': project.pk}))
@ -239,7 +239,6 @@ class CustomerProjectDeleteView(View):
project = form.cleaned_data.get('pk')
project.state = 'deleted'
project.save()
messages.info(req, 'Проект удалён навсегда')
else:
messages.info(req, 'Произошла ошибка: <pre>{msg}</pre>'.format(msg=pformat(form.errors)))

@ -0,0 +1 @@
default_app_config = 'specializations.apps.SpecializationConfig'

@ -0,0 +1,9 @@
<div class="dashedCol4">
<p class="specUser">Специализации:</p>
{% for spec in specializations %}
<div class="insetSpec">
<span>{{ spec }}</span>
<span>2-й</span>
</div>
{% endfor %}
</div>

@ -0,0 +1,18 @@
from django import template
from common.utils import get_or_none
from users.models import User
register = template.Library()
@register.inclusion_tag('templatetags/specializations_widget.html', takes_context=True)
def specialization_widget(context, user_id):
user_id = int(user_id)
user = get_or_none(User, pk=user_id)
if user:
specializations = user.contractor_specializations.all()
else:
specializations = None
return {
'specializations': specializations,
'user_id': user_id,
}

@ -35,11 +35,11 @@
<div class="imgProfile">
{% if request.user.is_contractor %}
<a href="{% url 'users:contractor-profile' pk=request.user.pk %}">
<img src="img/profile.jpg" alt="profile-image">
<img src="/media/img/profile.jpg" alt="profile-image">
</a>
{% elif request.user.is_customer %}
<a href="{% url 'users:customer-profile-open-projects' pk=request.user.pk %}">
<img src="img/profile.jpg" alt="profile-image">
<img src="/media/img/profile.jpg" alt="profile-image">
</a>
{% endif %}
</div>

@ -11,7 +11,9 @@ class UserEditForm(ModelForm):
def __init__(self, *args, **kwargs):
# import code; code.interact(local=dict(globals(), **locals()))
super().__init__(*args, **kwargs)
self.fields['contractor_specializations'].queryset = kwargs.get('instance').contractor_specializations.all()
if kwargs.get('instance'):
if kwargs.get('instance').is_contractor():
self.fields['contractor_specializations'].queryset = kwargs.get('instance').contractor_specializations.all()
class Meta:
model = User

@ -134,6 +134,10 @@ class User(AbstractBaseUser, PermissionsMixin):
def is_customer(self):
return self.groups.filter(name='Заказчики').exists()
def is_owner_profile(self, user_id):
pass
# return
class Team(models.Model):
name = models.CharField(max_length=255)

@ -16,8 +16,9 @@
</div>
<div class="menuUser disTab">
<ul>
<li class="icon_um1">
<a href="javascript:void(0)">
<a href="{% url 'users:contractor-edit' pk=contractor.pk %}">
редактировать профиль
</a>
<span></span>
@ -46,53 +47,22 @@
<div class="col-lg-9 divCol9">
<div class="col-lg-4">
<p class="nameUser">
Иванов Петр Иванович [ivanov_petr]
{{ contractor.get_full_name }}[ivanov_petr]
</p>
<p class="cityUser">Россия, Москва</p>
<p class="navv">На сайте 8 лет и 3 месяца</p>
<div class="statusUser">Свободен</div>
{% if contractor.is_free %}
<div class="statusUser">Свободен</div>
{% endif %}
<a href="javascript:void(0)" class="showCon">показать контакты</a>
</div>
<div class="col-lg-4">
<div class="dashedCol4">
<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="insetSpec">
<span>Архитектура</span>
<span>3-й</span>
</div>
<div class="insetSpec">
<span>3D Моделирование</span>
<span>100-й</span>
</div>
</div>
{% load specializtions_tags %}
{% specialization_widget contractor.pk %}
</div>
<div class="col-lg-4">
<ul class="rettList">
<li><a href="javascript:void(0)">Рейтинг: <span> 0</span></a></li>
<li><a href="javascript:void(0)">Безопасные сделки: <span> 0</span></a></li>
<li>
<a href="javascript:void(0)">
Отзывы:
<span> + 0</span>
<small> 0</small>
<mark> - 0</mark>
</a>
</li>
</ul>
{% load projects_tags %}
{% ratings_widget contractor.pk %}
<div class="sroUser">
<div class="iconSRO"></div>
<p>Есть допуск СРО</p>
@ -130,7 +100,7 @@
{% for p in user.portfolio.all %}
<div class="col-lg-4">
<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 ;">
<div class="imgFigure"></div>
</div>
</div>
@ -164,23 +134,20 @@
</p>
</div>
<div class="galleryWork2 disTab">
<div class="col-lg-4">
{% for ws in user.work_sell.all %}
<div class="col-lg-4">
<div class="insetCol box-sizing disTab">
<div class="imgGal">
<div class="imgGal" style="background:rgba(0, 0, 0, 0) url('/media/{{ ws.img }}') no-repeat scroll center center / cover ;">
<div class="imgFigure"></div>
</div>
<div class="cenaImg box-sizing">
<div class="cenaImgInset">
35 000 <i class="fa fa-rub"></i>
{{ ws.price }} <i class="fa fa-rub"></i>
</div>
</div>
</div>
<div class="insetCol2 box-sizing disTab">
<p>
Визуализация
загородного
дома 1500m2
</p>
<p>{{ ws }}</p>
<div class="buttonsImg" disTab>
<div class="insetBI insetBI1">
<i class="fa fa-pencil"></i>
@ -191,7 +158,7 @@
</div>
</div>
</div>
{% endfor %}
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="linkElse">
@ -219,10 +186,10 @@
</div>
<div class="col-lg-9">
<div class="top-summary">
<p class="name-summ">Иванов Петр Сергеевич</p>
<p class="name-summ">{{ user.get_full_name }}</p>
<a href="javascript:void(0)" class="download-summ">скачать резюме</a>
<p class="who-summ">
Мужчина, 24 года, 14 февраля 1991
Мужчина, 24 года, {{ user.date_of_birth }}
</p>
<div class="list-summ-block">
<div class="col-lg-4">
@ -256,20 +223,12 @@
<div class="pluss">
<p>Что я умею 1?</p>
<span>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut perspiciatis ducimus ullam saepe sed! Architecto sit, repellendus illo ut odio amet facilis distinctio veniam nulla consequatur a sequi deleniti aperiam!
</span>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. </span>
</div>
<div class="pluss">
<p>Что я умею 2?</p>
<span>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut perspiciatis ducimus ullam saepe sed! Architecto sit, repellendus illo ut odio amet facilis distinctio veniam nulla consequatur a sequi deleniti aperiam!
</span>
</div>
<div class="pluss">
<p>Что я умею 3?</p>
<span>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut perspiciatis ducimus ullam saepe sed! Architecto sit, repellendus illo ut odio amet facilis distinctio veniam nulla consequatur a sequi deleniti aperiam!
</span>
Lorem ipsum dolor sit amet, consectetur adipisicing elit.</span>
</div>
</div>
<div class="gal-pluss">

@ -1,7 +1,7 @@
{% extends 'partials/base.html' %}
{% load user_tags %}
{% load staticfiles %}
{% block content %}
{% include 'partials/header.html' %}
@ -9,7 +9,7 @@
<div class="row">
{% include 'partials/customer_profile_info_block.html' %}
<h1>Current projects will be here</h1>
<h1>Текущие проекты</h1>
{% include 'partials/footer.html' %}
</div>

@ -0,0 +1,176 @@
{% extends 'partials/base.html' %}
{% load staticfiles %}
{% block content %}
{% include 'partials/header.html' %}
<div class="container mainScore">
<div class="row">
<form method="post" enctype="multipart/form-data">{% csrf_token %}
<div class="projectsBlock disTab">
<div class="col-lg-12">
{{ form.errors }}
<div class="col-lg-3 divCol3">
<div class="avatar">
<div class="avatarInset">
<img src="/media/{{ form.avatar.value }}" alt="profile-image">
</div>
</div>
<div class="menuUser upload-img disTab">
<div class="upload2 up-l1">
<input type="file" name="{{ form.avatar.name }}">
<p>Загрузить фотографию</p>
</div>
</div>
</div>
<div class="col-lg-9 divCol9">
<div class="col-lg-4">
<p class="name-edit-p">ФИО:</p>
<input type="text" value="{{ form.first_name.value }}" name="{{ form.first_name.name }}" class="box-sizing inp-edit">
<input type="text" value="{{ form.last_name.value }}" name="{{ form.last_name.name }}" class="box-sizing inp-edit">
<input type="text" value="{{ form.patronym.value }}" name="{{ form.patronym.name }}" class="box-sizing inp-edit">
</div>
<div class="col-lg-4">
<p class="name-edit-p">Местоположение: {{ form.location.value }}</p>
<div class="polsF1 pols-edit disTab">
<select id="location-country">
</select>
<select id="location-region">
</select>
<select id="location-city" name="{{ form.location.name }}">
</select>
</div>
</div>
</div>
</div>
</div>
<div class="buttonGP btn-edit disTab">
<div class="btn-group valProject valProject2" role="group" aria-label="...">
<button type="button" class="btn btn-default">Общая информация</button>
</div>
</div>
<div class="col-lg-12 col12 new-filter">
<div class="filter clearfix">
<div class="titleF1 disTab">
<div class="col-lg-7">Дата рождения:</div>
<div class="col-lg-5">Пол:</div>
</div>
<div class="polsF1 disTab">
<div class="col-lg-7">
{{ form.date_of_birth }}
</div>
<div class="col-lg-5 dog-new ed-new">
<label><input type="radio" name="{{ form.gender }}"><span></span></label>
<p>Мужской</p>
<label class="woman"><input type="radio" name="{{ form.gender }}"><span></span></label>
<p>Женский</p>
</div>
</div>
<div class="titleF1 titleF2 disTab">
<div class="col-lg-3">Сайт:</div>
<div class="col-lg-3">Skype:</div>
{# <div class="col-lg-3">Электронная почта:</div>#}
<div class="col-lg-3">Телефон:</div>
</div>
<div class="searchF1 polsF1 polsFF polsF3">
<div class="col-lg-3">
<input type="text" name="{{ form.website.name }}"class="box-sizing surr surr2" placeholder="beeg.com">
</div>
<div class="col-lg-3">
<input type="text" name="{{ form.skype.name }}" class="box-sizing surr surr2" placeholder="nokia770">
</div>
{# <div class="col-lg-3">#}
{# <input type="text" name="{{ form.phone.name }}" class="box-sizing surr surr2" placeholder="example@gmail.com">#}
{# </div>#}
<div class="col-lg-3">
<input type="text" name="{{ form.phone.name }}" class="box-sizing surr surr2" placeholder="+7 999 999 44 02">
</div>
</div>
<div class="col-lg-12">
<div class="col-lg-12 make-new make-eed">
<label>{{ form.cro }}<span></span></label>
<p>Есть допуск СРО</p>
</div>
</div>
<div class="searchF1 polsF1 polsFF links-filter">
<input class="btn-submit-link" type="submit" value="Сохранить" />
</div>
</div>
</div>
</form>
{% include 'partials/footer.html' %}
</div>
</div>
{% endblock %}
{% block js_block %}
<script type="text/javascript">
$(function(){
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
$("#add-edit-spec").on('click',function(){
$("<select class='selectpicker4'><option >Видное</option></select>").insertBefore("#add-edit-spec");
$('.selectpicker4').selectpicker({
style: 'btn-info',
size: 4,
width: '237px'
});
});
var csrftoken = getCookie('csrftoken');
$.ajax({
url: '/api/location',
type: 'GET',
data:{ csrfmiddlewaretoken : csrftoken},
dataType:'json',
'success': function(json){
console.log(json.results);
var out = ''
var outCountry = '';
$.each(json.results, function(i,v){
if (v.type == 'country'){
outCountry += '<option value="' + v.id + '">' + v.name + '</option>';
}
if (v.type == 'town') {
out += '<option value="' + v.id + '">' + v.name + '</option>';
}
});
$('#location-country').html(outCountry);
$('#location-city').html(out);
$('#location-country').addClass("selectpicker4");
$('#location-city').addClass("selectpicker4");
$('.selectpicker4').selectpicker({
style: 'btn-info',
size: 4,
width: '237px'
});
}
});
});
</script>
{% endblock %}

@ -1,4 +1,5 @@
{% extends 'partials/base.html' %}
{% load staticfiles %}
{% block content %}
{% include 'partials/header.html' %}

@ -1,8 +1,9 @@
{% load staticfiles %}
<div class="col-lg-12">
<div class="col-lg-3 divCol3">
<div class="avatar new-mar">
<div class="avatarInset">
<img src="img/profile.jpg" alt="profile-image">
<img src="{% static 'img/profile.jpg' %}" alt="profile-image">
</div>
</div>
</div>
@ -13,30 +14,19 @@
{{ object.get_full_name }} [ivanov_petr]
</p>
<p class="cityUser">Россия, Москва</p>
<p class="cityUser">{{ object.location.name }}</p>
<p class="navv">На сайте {{ object.created }}</p>
</div>
<div class="col-lg-4 new-er">
<ul class="rettList">
<li><a href="javascript:void(0)">Рейтинг: <span> 0</span></a></li>
<li><a href="javascript:void(0)">Безопасные сделки: <span> 0</span></a></li>
<li>
<a href="javascript:void(0)">
Отзывы:
<span> + 0</span>
<small> 0</small>
<mark> - 0</mark>
</a>
</li>
</ul>
{% load projects_tags %}
{% ratings_widget customer.pk %}
</div>
<div class="col-lg-4">
<a href="javascript:void(0)" class="new-prop new-prop1">показать контакты</a>
<a href="javascript:void(0)" class="new-prop new-prop2">написать сообщение</a>
<a href="javascript:void(0)" class="new-red">редактировать профиль</a>
<a href="{% url 'users:customers-edit' pk=customer.pk %}" class="new-red">редактировать профиль</a>
</div>
</div>

@ -11,6 +11,7 @@ from .views import (
CustomerProfileReviewsView,
CustomerProfileTrashedProjectsView,
ContractorFinancialInfoEdit,
CustomerProfileEditView,
# UserDetailView,
# UserInfoListView,
UserListView,
@ -34,5 +35,6 @@ urlpatterns = [
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'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'contractors/(?P<pk>\d+)/financialinfo/edit/$', ContractorFinancialInfoEdit.as_view(), name='contractor-financical' ),
]

@ -69,6 +69,26 @@ class CustomerProfileReviewsView(BaseMixin, DetailView):
context_object_name = 'customer'
class CustomerProfileEditView(CheckForUserMixin, View):
form_class = UserEditForm
template_name = 'customer_profile_edit.html'
def get(self, request, *args, **kwargs):
instance = get_object_or_404(User, pk=request.user.pk)
form = self.form_class(instance=instance)
return render(request,self.template_name, {'form': form })
def post(self, request, *args, **kwargs):
instance = request.user
form = self.form_class(request.POST, request.FILES, instance=instance)
if form.is_valid():
# import code; code.interact(local=dict(globals(), **locals()))
form.save()
messages.info(request, 'Отправили post запрос')
return redirect(reverse('users:customer-profile-open-projects', kwargs={'pk': request.user.pk}))
return render(request, self.template_name, {'form': form})
class ContractorProfileEditView(CheckForUserMixin, View):
form_class = UserEditForm
template_name = 'contractor_profile_edit.html'
@ -83,7 +103,8 @@ class ContractorProfileEditView(CheckForUserMixin, View):
form = self.form_class(request.POST, request.FILES, instance=instance)
if form.is_valid():
# import code; code.interact(local=dict(globals(), **locals()))
form.save()
instance = form.save(commit=False)
instance.save()
messages.info(request, 'Данные успешно отредактированы')
return redirect(reverse('users:contractor-edit', kwargs={'pk': request.user.pk}))
@ -111,7 +132,3 @@ class ContractorFinancialInfoEdit(CheckForUserMixin, View):
return redirect(reverse('users:contractor-financical', kwargs={'pk': request.user.pk}))
return render(request, self.template_name,{'form': form})

@ -1,3 +1,4 @@
from django.contrib import admin
from .models import WorkSell
# Register your models here.
admin.site.register(WorkSell)

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-06-21 09:59
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 = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('work_sell', '0002_auto_20160607_1755'),
]
operations = [
migrations.AlterModelOptions(
name='worksell',
options={'verbose_name': 'Готовая работа', 'verbose_name_plural': 'Готовые работы'},
),
migrations.AddField(
model_name='worksell',
name='contractor',
field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, related_name='work_sell', to=settings.AUTH_USER_MODEL),
preserve_default=False,
),
]

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-06-21 10:19
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('work_sell', '0003_auto_20160621_1259'),
]
operations = [
migrations.AddField(
model_name='worksell',
name='price',
field=models.DecimalField(decimal_places=0, default=0, max_digits=10),
),
]

@ -1,9 +1,16 @@
from django.db import models
from users.models import User
class WorkSell(models.Model):
name = models.CharField(max_length=255)
description = models.TextField(blank=True)
img = models.ImageField(upload_to='worksell/worksell')
price = models.DecimalField(max_digits=10, decimal_places=0, default=0)
contractor = models.ForeignKey(User, related_name='work_sell')
def __str__(self):
return self.name
class Meta:
verbose_name = 'Готовая работа'
verbose_name_plural = 'Готовые работы'

Loading…
Cancel
Save