from generic_relations.relations import GenericRelatedField from rest_framework import serializers from rest_framework.serializers import ModelSerializer, ImageField, FileField, PrimaryKeyRelatedField from common.serializers import LocationSerializer, ContentTypeSerializer from specializations.serializers import SpecializationSerializer from users.models import User, Team from users.serializers import UserSerializer, TeamSerializer from .models import Project, Realty, BuildingClassfication, ConstructionType, Order, Stage, Portfolio, PortfolioPhoto, \ Answer, AnswerFile 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 fields = ( 'id', 'name', ) class ConstructionTypeSerializer(ModelSerializer): class Meta: model = ConstructionType fields = ( 'id', 'name', ) class RealtySerializer(ModelSerializer): building_classification = BuildingClassficationSerializer() construction_type = ConstructionTypeSerializer() location = LocationSerializer() user = UserSerializer() class Meta: model = Realty fields = ( 'id', 'name', 'building_classification', 'construction_type', 'location', 'user', ) class StageSerializer(ModelSerializer): term = serializers.DateField(format="%d.%m.%Y", input_formats=['%d.%m.%Y', ]) def validate(self, data): if 'pos' in data and data['pos'] > 1: pos = data['pos'] - 1 stage_last = Stage.objects.filter(order=data['order'], pos=pos) if stage_last: stage_last = stage_last[0] if stage_last.term > data['term']: raise serializers.ValidationError({'term': 'Дата не должна быть меньше даты предыдущео этапа'}) return data class Meta: model = Stage fields = ( 'id', 'cost', 'cost_type', 'term', 'term_type', 'name', 'order', 'result', 'pos', 'status', 'is_paid', 'close_contractor', 'close_customer', ) class OrderSerializer_(ModelSerializer): contractor = UserSerializer() stages = StageSerializer(many=True) team = TeamSerializer() project_id = PrimaryKeyRelatedField(read_only=True, source='project') class Meta: model = Order fields = ( 'created', 'id', 'secure', 'status', 'contractor', 'project_id', 'stages', 'team', ) 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() 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', 'cro', 'currency', 'customer', 'deal_type', 'id', 'name', 'order', 'price_and_term_required', 'realty', 'specialization', 'state', 'term', 'term_type', 'text', 'work_type', ) class OrderSerializer(ModelSerializer): stages = StageSerializer(many=True, read_only=True) project = ProjectSerializer(read_only=True) has_user_review = serializers.SerializerMethodField(read_only=True) contractor_name = serializers.SerializerMethodField(read_only=True) class Meta: model = Order fields = ( 'id', 'contractor', 'team', 'created', 'project', 'secure', 'status', 'has_user_review', 'stages', 'project', 'contractor_name', ) def get_contractor_name(self, obj): if obj.contractor: return obj.contractor.get_full_name() or obj.contractor.username elif obj.team: return obj.team.owner.get_full_name() or obj.team.owner.username else: return 'Исполнитель не определен' def get_has_user_review(self, obj): curr_user = self.context['request'].user if curr_user.is_customer(): return curr_user.customer_reviews.filter(project=obj.project).exists() elif curr_user.is_contractor(): if obj.team is None and obj.contractor: return curr_user.contractor_reviews.filter(project=obj.project).exists() elif curr_user.team: return curr_user.team.team_reviews.filter(project=obj.project).exists() else: return False class PortfolioSerializer(ModelSerializer): # answers = AnswerSerializer(many=True) building_classification = BuildingClassficationSerializer() construction_type = ConstructionTypeSerializer() location = LocationSerializer() photos = PortfolioPhotoSerializer(many=True) specialization = SpecializationSerializer() user = UserSerializer() class Meta: model = Portfolio fields = ( # 'answers', 'building_classification', 'construction_type', 'location', 'photos', 'specialization', 'user', 'budget', 'currency', 'description', 'id', 'name', 'term', 'term_type', 'worksell', ) class AnswerSerializer(ModelSerializer): content_type = ContentTypeSerializer() files = AnswerFileSerializer(many=True) portfolios = PortfolioSerializer(many=True) project = ProjectSerializer() author = GenericRelatedField({ User: UserSerializer(), Team: TeamSerializer() }) class Meta: model = Answer fields = ( 'budget', 'created', 'currency', 'id', 'is_archive', 'object_id', 'rejected', 'secure_deal_only', 'term', 'term_type', 'author', # Generic related field 'content_type', 'files', 'portfolios', 'project', # 'candidates', )