From 47e7f6ed4fbd19719c57c8d66a4cf9c4c586ad58 Mon Sep 17 00:00:00 2001 From: Nazar Kotiuk Date: Mon, 29 Dec 2014 10:33:18 +0200 Subject: [PATCH] Company and user rating. Company page with editing --- accounts/models.py | 35 +- company/edit_forms.py | 8 + company/edit_views.py | 21 + company/models.py | 39 +- company/urls.py | 21 +- company/views.py | 88 ++- exposition/models.py | 2 +- templates/client/company/companies_list.html | 25 + templates/client/company/company_detail.html | 28 + .../client/includes/company/company_edit.html | 581 ++++++++++++++++++ .../client/includes/company/company_list.html | 10 +- 11 files changed, 835 insertions(+), 23 deletions(-) create mode 100644 templates/client/company/companies_list.html create mode 100644 templates/client/company/company_detail.html create mode 100644 templates/client/includes/company/company_edit.html diff --git a/accounts/models.py b/accounts/models.py index 2eaad1bb..57d758ee 100644 --- a/accounts/models.py +++ b/accounts/models.py @@ -115,7 +115,7 @@ class User(AbstractBaseUser, PermissionsMixin): username = models.CharField(verbose_name='Email', max_length=255, unique=True, db_index=True) first_name = models.CharField(verbose_name='First name', max_length=255) last_name = models.CharField(verbose_name='Last name', max_length=255) - + rating = models.IntegerField(default=100)# добавить индекс в базе url = models.SlugField(blank=True) # is_active = models.BooleanField(default=0) # СДЕЛАТЬ проверку на емейле @@ -195,10 +195,12 @@ class User(AbstractBaseUser, PermissionsMixin): return n def get_permanent_url(self): - if self.url: - return self.catalog+self.url+'/' - return self.catalog+str(self.id)+'/' + if self.url: + return '/%s'%self.url + #return self.catalog+self.url+'/' + return '/%d'%self.id + #return self.catalog+str(self.id)+'/' def get_expos(self): """ @@ -351,6 +353,29 @@ class EventFilter(models.Model): +def calculate_rating(user): + user_rating_fields = {'position': 5, 'company': 5, 'url': 10} + profile_rating_fields = {'country': 5, 'city': 5, 'phone': 10, 'facebook': 5, 'twitter': 5, 'linkedin': 5, 'vk': 5, + 'web_page': 10, 'avatar': 20, 'about': 15} + # доделать "Отметки на выставках, за каждую", "Подписка на рассылку", "Добавление фото, за каждую", "Добавление компании, за каждую опубликованную" + + # base rating + rating = 100 + for key, value in user_rating_fields.iteritems(): + if getattr(user, key): + rating += value + + + for key, value in profile_rating_fields.iteritems(): + if getattr(user.profile, key): + rating += value + + user.rating = rating + # call to prevent recursion + post_save.disconnect(create_user_inf, sender=User) + user.save() + post_save.connect(create_user_inf, sender=User) + def create_user_inf(sender, instance, created, **kwargs): if created: @@ -358,6 +383,8 @@ def create_user_inf(sender, instance, created, **kwargs): Profile.objects.create(user=instance) EventFilter.objects.create(user=instance) + calculate_rating(instance) + post_save.connect(create_user_inf, sender=User) #need import after User Model, because User imported in "organiser.models" diff --git a/company/edit_forms.py b/company/edit_forms.py index fd4dab69..d7751b57 100644 --- a/company/edit_forms.py +++ b/company/edit_forms.py @@ -9,6 +9,14 @@ from company.models import Company class BaseForm(forms.ModelForm): translation = False + +class LogoForm(BaseForm): + logo = forms.ImageField(label=_(u'Выберите файл (GIF, JPG, PNG. Размер 100 × 100 пикселей)'), + required=False, widget=forms.FileInput(attrs={'class': 'input'})) + class Meta: + model = Company + fields = ('logo',) + class NameForm(BaseForm): name = forms.CharField(label=_(u'Введите название компании')) translation = True diff --git a/company/edit_views.py b/company/edit_views.py index bb2014af..00ce6279 100644 --- a/company/edit_views.py +++ b/company/edit_views.py @@ -1,6 +1,7 @@ import json from django.http import HttpResponseRedirect, HttpResponse, Http404 from django.utils.translation import get_language +from sorl.thumbnail import get_thumbnail from edit_forms import * from accounts.views import ProfileInvalidView @@ -20,6 +21,26 @@ class BaseView(ProfileInvalidView): return HttpResponse(json.dumps(response), content_type='application/json') +class LogoView(BaseView): + """ + instance profile. save user avatar. + + if call is ajax- return json data, else redirect to profile page + """ + form_class = LogoForm + + def form_valid(self, form): + company = self.request.user.company + form = self.form_class(self.request.POST, self.request.FILES, instance=company) + form.save() + if self.request.is_ajax(): + im = get_thumbnail(company.logo, '100x100', crop='center') + response = {'success': True, 'url': im.url} + return HttpResponse(json.dumps(response), content_type='application/json') + else: + return HttpResponseRedirect(company.get_permanent_url()) + + class NameView(BaseView): form_class = NameForm diff --git a/company/models.py b/company/models.py index ee471847..69be58f3 100644 --- a/company/models.py +++ b/company/models.py @@ -1,5 +1,7 @@ # -*- coding: utf-8 -*- +import os from django.db import models +from django.db.models.signals import post_save from hvad.models import TranslatableModel, TranslatedFields, TranslationManager from django.contrib.contenttypes import generic from django.utils import translation @@ -7,7 +9,10 @@ from django.utils.translation import ugettext as _ from functions.custom_fields import LocationField from functions.models_methods import ExpoManager from functions.model_mixin import ExpoMixin +from functions.signal_handlers import post_save_handler +def get_storage_path(instance, filename): + return os.path.join('company', filename) class Company(TranslatableModel, ExpoMixin): """ @@ -57,9 +62,14 @@ class Company(TranslatableModel, ExpoMixin): descriptions = models.CharField(max_length=255), keywords = models.CharField(max_length=255), ) + rating = models.IntegerField(default=100) # добавить индекс в базе #fields saves information about creating and changing model created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True) + logo = models.ImageField(upload_to=get_storage_path, blank=True) + + class Meta: + ordering = ['-rating', 'id'] def __unicode__(self): @@ -78,8 +88,7 @@ class Company(TranslatableModel, ExpoMixin): return '/members/' def get_permanent_url(self): - url = '%smember-%s'%(self.catalog, self.url) - return url + return '%s%s/'%(self.catalog, self.url) def get_expositions_number(self): return len(self.exposition_companies.all()) @@ -108,6 +117,26 @@ class Company(TranslatableModel, ExpoMixin): return list(expositions)+ list(conferences)+list(seminars)+list(webinars) -from django.db.models.signals import post_save -from functions.signal_handlers import post_save_handler -post_save.connect(post_save_handler, sender=Company) +def calculate_rating(company): + rating_simple = {'country': 5, 'city': 5, 'address_inf': 10, 'phone': 10, 'fax': 5, 'email': 10, + 'facebook': 5, 'twitter': 5, 'linkedin': 5, 'vk': 5, 'web_page': 10, #'logo': 20, + 'specialization': 5, 'description':15, 'foundation': 5, 'staff_number': 5}# участие и посещение доделать + rating_methods = {'theme': 10, 'tag': 5, 'photo':5} + # base rating + rating = 100 + for key, value in rating_simple.iteritems(): + if getattr(company, key): + rating += value + + company.rating = rating + # call to prevent recursion + post_save.disconnect(create_company, sender=Company) + company.save() + post_save.connect(create_company, sender=Company) + + +def create_company(sender, instance, created, **kwargs): + post_save_handler(sender, instance=instance, **kwargs) + calculate_rating(instance) + +post_save.connect(create_company, sender=Company) diff --git a/company/urls.py b/company/urls.py index 356bb237..b1d47572 100644 --- a/company/urls.py +++ b/company/urls.py @@ -1,15 +1,24 @@ # -*- coding: utf-8 -*- from django.conf.urls import patterns, url -from views import CompanyView, CompanySearchView +from views import CompanyView, CompanySearchView, MemberDetail, MemberList, MemberTagList, MemberThemeList from django.contrib.auth.decorators import login_required from edit_views import * + urlpatterns = patterns('', url(r'members/search/$', CompanySearchView.as_view()), - url(r'members/(?P.*)/(?P\d+)/$', CompanyView.as_view()), - url(r'members/(?P\d+)/$', CompanyView.as_view()), - url(r'members/(?P.*)/$', CompanyView.as_view()), - url(r'members/$', CompanyView.as_view()), + #url(r'members/(?P.*)/(?P\d+)/$', CompanyView.as_view()), + #url(r'members/(?P\d+)/$', CompanyView.as_view()), + #url(r'members/(?P.*)/$', CompanyView.as_view()), + #url(r'members/$', CompanyView.as_view()), + url(r'members/theme/(?P.*)/page/(?P\d+)/$', MemberThemeList.as_view()), + url(r'members/theme/(?P.*)/$', MemberThemeList.as_view()), + url(r'members/tag/(?P.*)/page/(?P\d+)/$', MemberTagList.as_view()), + url(r'members/tag/(?P.*)/$', MemberTagList.as_view()), + url(r'members/page/(?P\d+)/$', MemberList.as_view()), + url(r'members/(?P.*)/$', MemberDetail.as_view()), + url(r'members/$', MemberList.as_view()), + # url(r'company/create-company/$', 'company.views.create_company'), url(r'company/get-company/$', 'company.views.get_company'), @@ -26,4 +35,6 @@ urlpatterns = patterns('', url(r'^company/update/staff/$', login_required(StaffView.as_view())), url(r'^company/update/description/$', login_required(DescriptionView.as_view())), url(r'^company/update/address/$', login_required(AddressView.as_view())), + url(r'^company/update/logo/$', login_required(LogoView.as_view())), + ) diff --git a/company/views.py b/company/views.py index e5cfb0c0..f3244d9f 100644 --- a/company/views.py +++ b/company/views.py @@ -1,12 +1,21 @@ # -*- coding: utf-8 -*- import json from django.http import HttpResponse -from functions.custom_views import ExpoListView -from django.views.generic import ListView, FormView +from django.conf import settings +from django.views.generic import ListView, DetailView +from django.shortcuts import get_object_or_404 +from django.utils.translation import ugettext as _, get_language from haystack.query import EmptySearchQuerySet from models import Company +from theme.models import Theme, Tag from forms import CreateCompanyForm +from functions.custom_views import ExpoListView from functions.search_forms import CompanySearchForm +from .edit_forms import NameForm as CompNameForm, HomeForm as CompHomeForm, PhoneForm as CompPhoneForm,\ + EmailForm as CompEmailForm, WebPageForm as CompWebPageForm, SocialForm as CompSocialForm,\ + TagForm as CompTagForm, DescriptionForm as CompDescr, StaffForm as CompStaff, \ + FoundationForm as CompFound, SpecializationForm as CompSpec, AddressForm as CompAddress,\ + LogoForm as CompLogo class CompanySearchView(ListView): @@ -41,6 +50,81 @@ class CompanySearchView(ListView): return context + +class MemberList(ListView): + model = Company + paginate_by = settings.CLIENT_PAGINATION + template_name = 'client/company/companies_list.html' + search_form = CompanySearchForm + catalog_url = '/members/' + + def get_queryset(self): + return self.model.objects.order_by('-rating') + +class MemberThemeList(ListView): + model = Company + paginate_by = settings.CLIENT_PAGINATION + template_name = 'client/company/companies_list.html' + search_form = CompanySearchForm + catalog_url = '/members/' + + def get_queryset(self): + qs = super(MemberThemeList, self).get_queryset() + slug = self.kwargs.get('slug') + theme = get_object_or_404(Theme, url=slug) + qs = qs.filter(theme=theme) + return qs + + +class MemberTagList(ListView): + model = Company + paginate_by = settings.CLIENT_PAGINATION + template_name = 'client/company/companies_list.html' + search_form = CompanySearchForm + catalog_url = '/members/' + + def get_queryset(self): + qs = super(MemberTagList, self).get_queryset() + slug = self.kwargs.get('slug') + tag = get_object_or_404(Tag, url=slug) + qs = qs.filter(tag=tag) + return qs + + + + +class MemberDetail(DetailView): + model = Company + slug_field = 'url' + template_name = 'client/company/company_detail.html' + + + def get_context_data(self, **kwargs): + context = super(MemberDetail, self).get_context_data(**kwargs) + + company = context['object'] + if self.request.user == company.creator: + + forms = { + 'home_form': CompHomeForm(instance=company), 'phone_form': CompPhoneForm(instance=company), + 'email_form': CompEmailForm(instance=company), 'web_page_form': CompWebPageForm(instance=company), + 'social_form': CompSocialForm(instance=company), 'tag_form': CompTagForm(instance=company), + 'staff_form': CompStaff(instance=company), 'found_form': CompFound(instance=company), + 'logo_form': CompLogo(instance=company) + } + + lang = get_language() + comp_transl = company.translations.get(language_code=lang) + transl_forms = { + 'name_form': CompNameForm(instance=comp_transl), 'spec_form': CompSpec(instance=comp_transl), + 'description_form': CompDescr(instance=comp_transl), 'address_form': CompAddress(instance=comp_transl) + } + + context.update(forms) + context.update(transl_forms) + return context + + class CompanyView(ExpoListView): paginate_by = 10 model = Company diff --git a/exposition/models.py b/exposition/models.py index 78498b49..4d54b967 100644 --- a/exposition/models.py +++ b/exposition/models.py @@ -74,7 +74,7 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin): blank=True, null=True, related_name='exposition_users') photogallery = models.ForeignKey('photologue.Gallery', blank=True, null=True) logo = models.ImageField(verbose_name='Logo', upload_to='exposition/logo/', blank=True) - rating = models.IntegerField(default=0) + rating = models.IntegerField(default=0) # добавить индекс в базе quality_label = BitField(flags=['ufi', 'rsva', 'exporating']) visitors = models.PositiveIntegerField(verbose_name='Посетители', blank=True, null=True) diff --git a/templates/client/company/companies_list.html b/templates/client/company/companies_list.html new file mode 100644 index 00000000..4a2eebbe --- /dev/null +++ b/templates/client/company/companies_list.html @@ -0,0 +1,25 @@ +{% extends 'base_catalog.html' %} +{% load i18n %} + +{% block bread_scrumbs %} + +{% endblock %} + + +{% block page_title %} +
+

{% trans 'Участники' %}

+
+{% endblock %} + +{% block content_list %} + {% include 'includes/company/company_list.html' with object_list=object_list %} +{% endblock %} + +{% block paginator %} + {% include 'includes/catalog_paginator.html' with page_obj=page_obj %} +{% endblock %} \ No newline at end of file diff --git a/templates/client/company/company_detail.html b/templates/client/company/company_detail.html new file mode 100644 index 00000000..b13977b2 --- /dev/null +++ b/templates/client/company/company_detail.html @@ -0,0 +1,28 @@ +{% extends 'base_catalog.html' %} +{% load i18n %} + +{% block bread_scrumbs %} + +{% endblock %} + +{% block page_title %} +{% endblock %} + +{% block content_list %} + {% if request.user == object.creator %} + + {% include 'client/includes/company/company_edit.html' %} + {% else %} + {% include 'client/includes/company/company_object.html' with company=object %} + {% endif %} + + +{% endblock %} + +{% block paginator %} + +{% endblock %} \ No newline at end of file diff --git a/templates/client/includes/company/company_edit.html b/templates/client/includes/company/company_edit.html new file mode 100644 index 00000000..7d5f79b3 --- /dev/null +++ b/templates/client/includes/company/company_edit.html @@ -0,0 +1,581 @@ +{% load static %} +{% load i18n %} +{% load template_filters %} + +
+
+ + + +
+
+ + + +
+ {{ name_form.name.value }} + +
+ редактировать +
+
{% csrf_token %} + +
+ +
+ +
+ {{ name_form.name }} +
+
+ +
+ +
+ +
+
+ + закрыть +
+
+
+
+ + + + +
+ {% for th in request.user.company.theme.all %} + {{ th.name }}{% ifnotequal forloop.counter request.user.company.theme.all|length %},{% endifnotequal %} + {% endfor %} +
+ +
+ + + + +
+ + + +
+ +
+ +
+
+ редактировать профиль + завершить редактирование + +
Добавить профили в соц.сетях:
+ + + +
+ + +
+ +
+ +
+
Дополнительная информация
+ + + + + + + +
+ +
+
+
+{% block pre_scripts %} + + +{% endblock %} + +{% block scripts %} + + + + + + + + +{% endblock %} diff --git a/templates/client/includes/company/company_list.html b/templates/client/includes/company/company_list.html index 845e3d6b..dec449a1 100644 --- a/templates/client/includes/company/company_list.html +++ b/templates/client/includes/company/company_list.html @@ -6,7 +6,7 @@ {% for company in object_list %}
  • - +
    {% with obj=company %} {% include 'client/includes/show_logo.html' %} @@ -16,7 +16,7 @@
    - +
    @@ -37,7 +37,7 @@