From 5205b388ed565266541f3380a1b8086af1d53683 Mon Sep 17 00:00:00 2001 From: ArturBaybulatov Date: Thu, 15 Sep 2016 17:25:28 +0300 Subject: [PATCH] Fixes --- api/views.py | 18 +++- archilance/settings/base.py | 2 +- assets/index.js | 38 +++++--- assets/js/chat.js | 2 +- chat/filters.py | 17 ++-- common/filters.py | 16 +++- common/serializers.py | 28 ++++-- projects/filters.py | 61 ++++++++++--- projects/serializers.py | 113 ++++++++++++++++-------- reviews/filters.py | 10 +-- specializations/filters.py | 7 +- templates/partials/base.html | 2 +- users/filters.py | 4 +- users/templates/contractor_profile.html | 3 +- work_sell/filters.py | 3 +- 15 files changed, 230 insertions(+), 94 deletions(-) diff --git a/api/views.py b/api/views.py index 27d998f..1fd78be 100755 --- a/api/views.py +++ b/api/views.py @@ -13,7 +13,7 @@ from projects.serializers import ( from projects.filters import ( ProjectFilterSet, RealtyFilterSet, StageFilterSet, PortfolioFilterSet, OrderFilterSet, - PortfolioPhotoFilterSet, + PortfolioPhotoFilterSet, AnswerFilterSet, ) from specializations.models import Specialization @@ -22,7 +22,7 @@ from specializations.filters import SpecializationFilterSet from users.models import User, ContractorResumeFiles, ContractorResume, Team from users.serializers import UserSerializer, ContractorResumeFilesSerializer, ContractorResumeSerializer, TeamSerializer -from users.filters import UserFilterSet, ContractorResumeFilesFilterSet, ContractorResumeFilterSet +from users.filters import UserFilterSet, TeamFilterSet, ContractorResumeFilesFilterSet, ContractorResumeFilterSet from common.models import Location from common.serializers import LocationSerializer @@ -92,6 +92,16 @@ class ProjectViewSet(ModelViewSet): serializer_class = ProjectSerializer filter_class = ProjectFilterSet + def get_queryset(self): + qs = super().get_queryset() + + x_no_contractor_answer = self.request.GET.get('x_no_contractor_answer', '') + + if x_no_contractor_answer.isdecimal(): + qs = qs.exclude(answers__object_id=x_no_contractor_answer, answers__content_type__model='user') + + return qs + class NoteViewSet(ModelViewSet): queryset = Notes.objects.all() @@ -220,10 +230,10 @@ class WorkSellPhotoViewSet(ModelViewSet): class AnswerViewSet(ModelViewSet): queryset = Answer.objects.all() serializer_class = AnswerSerializer - # filter_class = AnswerFilterSet + filter_class = AnswerFilterSet class TeamViewSet(ModelViewSet): queryset = Team.objects.all() serializer_class = TeamSerializer - # filter_class = TeamFilterSet + filter_class = TeamFilterSet diff --git a/archilance/settings/base.py b/archilance/settings/base.py index 42c8493..86b3daf 100644 --- a/archilance/settings/base.py +++ b/archilance/settings/base.py @@ -266,7 +266,7 @@ if DEBUG: EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend' PAGE_SIZE = 10 # Non-api page size (regular views) -API_PAGE_SIZE = 1000 # Django REST framework +API_PAGE_SIZE = 100 # Django REST framework REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ diff --git a/assets/index.js b/assets/index.js index e24700b..8d2e35f 100644 --- a/assets/index.js +++ b/assets/index.js @@ -257,30 +257,42 @@ function initContractorSelect($select, excludeIds) { // Order offer project select --------------------------------------------- - -var projectSelectOptions = { - language: 'ru', - placeholder: 'Выберите проект', // Required by `allowClear` - allowClear: true, -} - -function initProjectSelect($select, customerId) { - return $.ajax({url: '/api/projects/?state=active&customer=' + customerId, method: 'GET', dataType: 'json'}) - .then(function(res) { +;(function() { + var projectSelectOptions = { + language: 'ru', + placeholder: 'Выберите проект', // Required by `allowClear` + allowClear: true, + } + + function initProjectSelect($select, customerId, contractorId) { + var urlObj = new URI('/api/projects/') + + urlObj.setQuery({ + state: 'active', + customer: customerId, + order__contractor__isnull: true, + order__team__isnull: true, + x_no_contractor_answer: contractorId, + }) + + return $.get(urlObj.href()).then(function(res) { var projects = res.results $select.select2(_.merge(projectSelectOptions, { data: _.map(function(project) { return { id: project.id, - text: project.name, + //text: project.name, + text: format('%s (%s)', project.name, project.id), // Tmp origItem: project, } }, projects), })) }) -} - + } + + window.initProjectSelect = initProjectSelect +}()) diff --git a/assets/js/chat.js b/assets/js/chat.js index 5ee15de..f770568 100644 --- a/assets/js/chat.js +++ b/assets/js/chat.js @@ -1,6 +1,6 @@ var SocketHandler = function () { domain = domain.replace(':' + port, ''); - var url = 'ws://' + domain + '/chat/' + userId + '/'; + var url = 'ws://' + domain + ':8888/chat/' + userId + '/'; var sock = new WebSocket(url); var intervalId; sock.onopen = function () { diff --git a/chat/filters.py b/chat/filters.py index 6e878f7..0b3da56 100644 --- a/chat/filters.py +++ b/chat/filters.py @@ -5,6 +5,7 @@ from .models import Message, Notes, Documents # # class DocumentsFilterSet(FilterSet): # file = AllLookupsFilter() +# id = AllLookupsFilter() # # sender = RelatedFilter('users.filters.UserFilterSet') # # recipent = RelatedFilter('users.filters.UserFilterSet') # # order = RelatedFilter('projects.filters.OrderFilterSet') @@ -15,13 +16,15 @@ from .models import Message, Notes, Documents class MessageFilterSet(FilterSet): - text = AllLookupsFilter() created = AllLookupsFilter() - sender = RelatedFilter('users.filters.UserFilterSet') - recipent = RelatedFilter('users.filters.UserFilterSet') + id = AllLookupsFilter() private_type = AllLookupsFilter() - team = RelatedFilter('users.filters.TeamFilterSet') + text = AllLookupsFilter() + order = RelatedFilter('projects.filters.OrderFilterSet') + recipent = RelatedFilter('users.filters.UserFilterSet') + sender = RelatedFilter('users.filters.UserFilterSet') + team = RelatedFilter('users.filters.TeamFilterSet') class Meta: model = Message @@ -39,10 +42,12 @@ class DocumentFilterSet(FilterSet): class NoteFilterSet(FilterSet): - text = AllLookupsFilter() created = AllLookupsFilter() - sender = RelatedFilter('users.filters.UserFilterSet') + id = AllLookupsFilter() + text = AllLookupsFilter() + recipent = RelatedFilter('users.filters.UserFilterSet') + sender = RelatedFilter('users.filters.UserFilterSet') class Meta: model = Notes diff --git a/common/filters.py b/common/filters.py index fbfd842..17689f8 100644 --- a/common/filters.py +++ b/common/filters.py @@ -1,17 +1,29 @@ +from django.contrib.contenttypes.models import ContentType from rest_framework_filters import FilterSet, AllLookupsFilter, RelatedFilter + from .models import Location class LocationFilterSet(FilterSet): - children = RelatedFilter('common.filters.LocationFilterSet') id = AllLookupsFilter() level = AllLookupsFilter() lft = AllLookupsFilter() name = AllLookupsFilter() - parent = RelatedFilter('common.filters.LocationFilterSet') rght = AllLookupsFilter() tree_id = AllLookupsFilter() type = AllLookupsFilter() + + children = RelatedFilter('common.filters.LocationFilterSet') + parent = RelatedFilter('common.filters.LocationFilterSet') class Meta: model = Location + + +class ContentTypeFilterSet(FilterSet): + app_label = AllLookupsFilter() + id = AllLookupsFilter() + model = AllLookupsFilter() + + class Meta: + model = ContentType diff --git a/common/serializers.py b/common/serializers.py index cc37b8c..9c455e4 100644 --- a/common/serializers.py +++ b/common/serializers.py @@ -1,3 +1,4 @@ +from django.contrib.contenttypes.models import ContentType from rest_framework.serializers import ModelSerializer from .models import Location @@ -8,15 +9,15 @@ class NestedLocationSerializer(ModelSerializer): model = Location fields = ( + 'children', 'id', + 'level', + 'lft', 'name', - 'children', 'parent', - 'type', - 'lft', 'rght', - 'level', 'tree_id', + 'type', ) @@ -28,13 +29,24 @@ class LocationSerializer(ModelSerializer): model = Location fields = ( + 'children', 'id', + 'level', + 'lft', 'name', - 'children', 'parent', - 'type', - 'lft', 'rght', - 'level', 'tree_id', + 'type', + ) + + +class ContentTypeSerializer(ModelSerializer): + class Meta: + model = ContentType + + fields = ( + 'app_label', + 'id', + 'model', ) diff --git a/projects/filters.py b/projects/filters.py index 5f20c98..b111a72 100755 --- a/projects/filters.py +++ b/projects/filters.py @@ -1,6 +1,16 @@ from rest_framework_filters import FilterSet, RelatedFilter, AllLookupsFilter -from .models import Project, Stage, Order, Realty, BuildingClassfication, ConstructionType, Portfolio, PortfolioPhoto +from .models import ( + Answer, + BuildingClassfication, + ConstructionType, + Order, + Portfolio, + PortfolioPhoto, + Project, + Realty, + Stage, +) class BuildingClassficationFilterSet(FilterSet): @@ -26,6 +36,7 @@ class ProjectFilterSet(FilterSet): cro = AllLookupsFilter() currency = AllLookupsFilter() deal_type = AllLookupsFilter() + id = AllLookupsFilter() name = AllLookupsFilter() price_and_term_required = AllLookupsFilter() state = AllLookupsFilter() @@ -34,7 +45,9 @@ class ProjectFilterSet(FilterSet): text = AllLookupsFilter() work_type = AllLookupsFilter() + answers = RelatedFilter('projects.filters.AnswerFilterSet') customer = RelatedFilter('users.filters.UserFilterSet') + order = RelatedFilter('projects.filters.OrderFilterSet') realty = RelatedFilter('projects.filters.RealtyFilterSet') specialization = RelatedFilter('specializations.filters.SpecializationFilterSet') @@ -42,31 +55,58 @@ class ProjectFilterSet(FilterSet): model = Project -class OrderFilterSet(FilterSet): - id = AllLookupsFilter() - contractor = RelatedFilter('users.filters.UserFilterSet') - team = RelatedFilter('users.filters.TeamFilterSet') +class AnswerFilterSet(FilterSet): + budget = AllLookupsFilter() created = AllLookupsFilter() + currency = AllLookupsFilter() + id = AllLookupsFilter() + is_archive = AllLookupsFilter() + object_id = AllLookupsFilter() + rejected = AllLookupsFilter() + secure_deal_only = AllLookupsFilter() + term = AllLookupsFilter() + term_type = AllLookupsFilter() + + # author = ... # ??? + + # messages = RelatedFilter('...') + content_type = RelatedFilter('common.filters.ContentTypeFilterSet') + contractors = RelatedFilter('users.filters.UserFilterSet') + portfolios = RelatedFilter('projects.filters.PortfolioFilterSet') project = RelatedFilter('projects.filters.ProjectFilterSet') + teams = RelatedFilter('users.filters.TeamFilterSet') + + class Meta: + model = Answer + + +class OrderFilterSet(FilterSet): + created = AllLookupsFilter() + id = AllLookupsFilter() secure = AllLookupsFilter() status = AllLookupsFilter() + + contractor = RelatedFilter('users.filters.UserFilterSet') + project = RelatedFilter('projects.filters.ProjectFilterSet') + team = RelatedFilter('users.filters.TeamFilterSet') class Meta: model = Order class StageFilterSet(FilterSet): + cost = AllLookupsFilter() + cost_type = AllLookupsFilter() id = AllLookupsFilter() + is_paid = AllLookupsFilter() name = AllLookupsFilter() + pos = AllLookupsFilter() result = AllLookupsFilter() - cost = AllLookupsFilter() + status = AllLookupsFilter() term = AllLookupsFilter() - cost_type = AllLookupsFilter() term_type = AllLookupsFilter() - status = AllLookupsFilter() - pos = AllLookupsFilter() + order = RelatedFilter('projects.filters.OrderFilterSet') - is_paid = AllLookupsFilter() class Meta: model = Stage @@ -87,6 +127,7 @@ class RealtyFilterSet(FilterSet): class PortfolioPhotoFilterSet(FilterSet): id = AllLookupsFilter() + portfolio = RelatedFilter('projects.filters.PortfolioFilterSet') # img = ??? diff --git a/projects/serializers.py b/projects/serializers.py index 07658ad..e17b96d 100755 --- a/projects/serializers.py +++ b/projects/serializers.py @@ -3,11 +3,40 @@ from generic_relations.relations import GenericRelatedField from rest_framework.serializers import ModelSerializer, ImageField, FileField, SerializerMethodField, PrimaryKeyRelatedField, ReadOnlyField from .models import Project, Realty, BuildingClassfication, ConstructionType, Order, Stage, Portfolio, PortfolioPhoto, Answer, AnswerFile -from common.serializers import LocationSerializer +from common.serializers import LocationSerializer, ContentTypeSerializer from specializations.serializers import SpecializationSerializer from users.models import User, Team from users.serializers import UserSerializer, TeamSerializer + +class AnswerFileSerializer(ModelSerializer): + file = FileField() + + class Meta: + model = AnswerFile + + fields = ( + 'file', + 'id', + 'name', + # 'answer', + ) + + +class PortfolioPhotoSerializer(ModelSerializer): + img = ImageField() + portfolio_id = PrimaryKeyRelatedField(read_only=True, source='portfolio') + + class Meta: + model = PortfolioPhoto + + fields = ( + 'id', + 'img', + 'portfolio_id', + ) + + class BuildingClassficationSerializer(ModelSerializer): class Meta: model = BuildingClassfication @@ -93,16 +122,53 @@ class OrderSerializer_(ModelSerializer): ) +class AnswerSerializer_(ModelSerializer): + project_id = PrimaryKeyRelatedField(read_only=True, source='project') + portfolio_ids = PrimaryKeyRelatedField(read_only=True, source='portfolios', many=True) + + content_type = ContentTypeSerializer() + files = AnswerFileSerializer(many=True) + + author = GenericRelatedField({ + User: UserSerializer(), + Team: TeamSerializer() + }) + + class Meta: + model = Answer + + fields = ( + 'budget', + 'created', + 'currency', + 'id', + 'is_archive', + 'object_id', + 'portfolio_ids', + 'project_id', + 'rejected', + 'secure_deal_only', + 'term', + 'term_type', + + 'author', # Generic related field + 'content_type', + 'files', + ) + + class ProjectSerializer(ModelSerializer): + answers = AnswerSerializer_(many=True) customer = UserSerializer() - specialization = SpecializationSerializer() - realty = RealtySerializer() order = OrderSerializer_() # TODO: Can't serialize a reverse/reciprocal relation + realty = RealtySerializer() + specialization = SpecializationSerializer() class Meta: model = Project - + fields = ( + 'answers', 'budget', 'budget_by_agreement', 'created', @@ -158,25 +224,10 @@ class OrderSerializer(ModelSerializer): return False -class PortfolioPhotoSerializer(ModelSerializer): - img = ImageField() - portfolio_id = PrimaryKeyRelatedField(read_only=True, source='portfolio') - - class Meta: - model = PortfolioPhoto - - fields = ( - 'id', - 'img', - 'portfolio_id', - ) - - class PortfolioSerializer(ModelSerializer): # answers = AnswerSerializer(many=True) building_classification = BuildingClassficationSerializer() construction_type = ConstructionTypeSerializer() - id = ReadOnlyField() location = LocationSerializer() photos = PortfolioPhotoSerializer(many=True) specialization = SpecializationSerializer() @@ -204,24 +255,11 @@ class PortfolioSerializer(ModelSerializer): ) -class AnswerFileSerializer(ModelSerializer): - file = FileField() - - class Meta: - model = AnswerFile - - fields = ( - 'file', - 'id', - 'name', - # 'answer', - ) - - class AnswerSerializer(ModelSerializer): + content_type = ContentTypeSerializer() files = AnswerFileSerializer(many=True) portfolios = PortfolioSerializer(many=True) - project = ProjectSerializer + project = ProjectSerializer() author = GenericRelatedField({ User: UserSerializer(), @@ -236,15 +274,18 @@ class AnswerSerializer(ModelSerializer): 'created', 'currency', 'id', + 'is_archive', + 'object_id', + 'rejected', 'secure_deal_only', 'term', 'term_type', - 'text', + 'author', # Generic related field + 'content_type', 'files', 'portfolios', 'project', - 'author', # Generic related field # 'candidates', ) diff --git a/reviews/filters.py b/reviews/filters.py index db9119c..7f65b47 100644 --- a/reviews/filters.py +++ b/reviews/filters.py @@ -4,15 +4,15 @@ from .models import Review class ReviewFilterSet(FilterSet): + created = AllLookupsFilter() + id = AllLookupsFilter() text = AllLookupsFilter() type = AllLookupsFilter() - created = AllLookupsFilter() - from_customer = RelatedFilter('users.filters.UserFilterSet') + from_contractor = RelatedFilter('users.filters.UserFilterSet') - target_customer = RelatedFilter('users.filters.UserFilterSet') + from_customer = RelatedFilter('users.filters.UserFilterSet') target_contractor = RelatedFilter('users.filters.UserFilterSet') + target_customer = RelatedFilter('users.filters.UserFilterSet') class Meta: model = Review - - diff --git a/specializations/filters.py b/specializations/filters.py index 53e667c..b690c10 100755 --- a/specializations/filters.py +++ b/specializations/filters.py @@ -2,15 +2,16 @@ from rest_framework_filters import FilterSet, RelatedFilter, AllLookupsFilter from .models import Specialization class SpecializationFilterSet(FilterSet): - children = RelatedFilter('specializations.filters.SpecializationFilterSet') id = AllLookupsFilter() level = AllLookupsFilter() lft = AllLookupsFilter() name = AllLookupsFilter() - parent = RelatedFilter('specializations.filters.SpecializationFilterSet') - projects = RelatedFilter('projects.filters.ProjectFilterSet') rght = AllLookupsFilter() tree_id = AllLookupsFilter() + children = RelatedFilter('specializations.filters.SpecializationFilterSet') + parent = RelatedFilter('specializations.filters.SpecializationFilterSet') + projects = RelatedFilter('projects.filters.ProjectFilterSet') + class Meta: model = Specialization diff --git a/templates/partials/base.html b/templates/partials/base.html index 6530a3f..75da402 100644 --- a/templates/partials/base.html +++ b/templates/partials/base.html @@ -86,7 +86,7 @@ if ((queryString.indexOf('/chat') != 0) && (queryString.indexOf('/users/contractor-office/510/work-projects') != 0)) { domain = domain.replace(':' + port, ''); - var url = 'ws://' + domain + '/chat/' + userId + '/'; + var url = 'ws://' + domain + ':8888/chat/' + userId + '/'; var sock = new WebSocket(url); var intervalId; sock.onopen = function () { diff --git a/users/filters.py b/users/filters.py index bc29452..5055a73 100755 --- a/users/filters.py +++ b/users/filters.py @@ -47,8 +47,8 @@ class TeamFilterSet(FilterSet): class ContractorResumeFilterSet(FilterSet): id = AllLookupsFilter() - text = AllLookupsFilter() resume_file = AllLookupsFilter() + text = AllLookupsFilter() class Meta: model = ContractorResume @@ -56,8 +56,8 @@ class ContractorResumeFilterSet(FilterSet): class ContractorResumeFilesFilterSet(FilterSet): id = AllLookupsFilter() - title = AllLookupsFilter() img = AllLookupsFilter() + title = AllLookupsFilter() resume = RelatedFilter('users.filters.ContractorResumeFilterSet') diff --git a/users/templates/contractor_profile.html b/users/templates/contractor_profile.html index 4a5fed1..2f089db 100644 --- a/users/templates/contractor_profile.html +++ b/users/templates/contractor_profile.html @@ -738,6 +738,7 @@ {% if request.user.is_customer %} var customerId = {{ request.user.pk }} + var contractorId = {{ contractor.pk }} var $projectSelectionModal = $('#projectSelectionModal') var projectUrl_ = '/projects/%id%/' var projectOrderChatUrl_ = '/chat/#order%orderId%' @@ -751,7 +752,7 @@ $that.data('modalOpenButton', $modalOpenButton) - initProjectSelect($projectSelect, customerId) + initProjectSelect($projectSelect, customerId, contractorId) }) diff --git a/work_sell/filters.py b/work_sell/filters.py index 50faa3c..a8e7137 100644 --- a/work_sell/filters.py +++ b/work_sell/filters.py @@ -15,9 +15,10 @@ class WorkSellFilter(django_filters.FilterSet): class WorkSellPhotoFilterSet(FilterSet): id = AllLookupsFilter() - work_sell = RelatedFilter('work_sell.filters.WorkSellFilterSet') # img = ??? + work_sell = RelatedFilter('work_sell.filters.WorkSellFilterSet') + class Meta: model = WorkSellPhoto