class InstanceSerializer(serializers.HyperlinkedModelSerializer): identity = IdentitySummarySerializer(source='created_by_identity') user = UserSummarySerializer(source='created_by') provider = ProviderSummarySerializer(source='created_by_identity.provider') status = serializers.CharField(source='esh_status', read_only=True) activity = serializers.CharField(source='esh_activity', read_only=True) projects = serializers.PrimaryKeyRelatedField(many=True, read_only=True) scripts = ModelRelatedField(many=True, required=False, queryset=BootScript.objects.all(), serializer_class=BootScriptSummarySerializer, style={'base_template': 'input.html'}) size = serializers.SerializerMethodField() image = serializers.SerializerMethodField() ip_address = serializers.SerializerMethodField() usage = serializers.SerializerMethodField() version = serializers.SerializerMethodField() uuid = serializers.CharField(source='provider_alias') url = UUIDHyperlinkedIdentityField(view_name='api:v2:instance-detail', uuid_field='provider_alias') def get_usage(self, instance): return instance.get_total_hours() def get_size(self, obj): size = obj.get_size() serializer = SizeSummarySerializer(size, context=self.context) return serializer.data def get_image(self, obj): image_uuid = obj.application_uuid() image = Image.objects.get(uuid=image_uuid) serializer = ImageSummarySerializer(image, context=self.context) return serializer.data def get_ip_address(self, obj): status = obj.esh_status() if status in ["suspended", "shutoff", "shelved"]: return "0.0.0.0" return obj.ip_address def get_version(self, obj): version = obj.source.providermachine.application_version serializer = ImageVersionSummarySerializer(version, context=self.context) return serializer.data class Meta: model = Instance fields = ( 'id', 'uuid', 'url', 'name', 'status', 'activity', 'size', 'ip_address', 'shell', 'vnc', 'identity', 'user', 'provider', 'image', 'version', # NOTE:Should replace image? 'usage', 'scripts', 'projects', 'start_date', 'end_date', )
class DailyStudentAttendanceSerializer(serializers.ModelSerializer): creator = serializers.SerializerMethodField(read_only=True) section = SectionSerializer(read_only=True) section_id = serializers.PrimaryKeyRelatedField( write_only=True, queryset=models.Section.objects.filter(is_active=True), source='section') class Meta: model = models.DailyStudentAttendance fields = ( 'id', 'section', 'section_id', 'date', 'session', 'created_by', 'creator', 'average_attendance', ) read_only_fields = ( 'creator', 'section', 'average_attendance', ) def get_creator(self, instance): if not instance.created_by: return None return { 'id': instance.created_by.id, 'fullname': instance.created_by.profile.fullname, } def validate_date(self, date): if models.DailyStudentAttendance.objects.filter( date=date, section_id=self.initial_data['section_id']).exists(): raise serializers.ValidationError( 'Attendance already exists for given date.') return date def validate_created_by(self, user): try: if self.context['request'].user.id == user.id: return user except: raise serializers.ValidationError('Invalid user id') else: raise serializers.ValidationError('Invalid user id') def create(self, validated_data): instance = models.DailyStudentAttendance.objects.create( **validated_data) # Create attendance items for each student in section student_ids = models.User.objects.filter( is_active=True, profile__student_info__section_id=instance.section_id).values_list( 'id', flat=True) student_ids = [id for id in student_ids] items = [] for id in student_ids: item = models.StudentAttendanceItem(attendance_id=instance.id, student_id=id, date=validated_data['date']) items.append(item) models.StudentAttendanceItem.objects.bulk_create(items) return instance
class ChangeApartmentSerializer(WritableNestedModelSerializer): owner = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault()) location = LocationSerializer() apartment_image = ApartmentImageSerializer(many=True) area = AreaSerializer() contact = ContactSerializer() detail = DetailSerializer() comments = CommentSerializer(many=True, read_only=True) orders = BookingSerializer(many=True, read_only=True) floor = serializers.IntegerField() storey = serializers.IntegerField() class Meta: model = Apartment fields = ('id', 'type', 'room', 'floor', 'area', 'series', 'title', 'construction_type', 'state', 'detail', 'location', 'price', 'currency', 'another_price', 'preview_image', 'description', 'pub_date', 'storey', 'nearby_objects', 'objects_in_apartment', 'apartment_image', 'contact', 'owner', 'comments', 'orders') def create(self, validated_data): location_data = validated_data.pop('location') area_data = validated_data.pop('area') contact_data = validated_data.pop('contact') detail_data = validated_data.pop('detail') area = Area.objects.create(**area_data) location = Location.objects.create(**location_data) contact = Contact.objects.create(**contact_data) detail = Detail.objects.create(**detail_data) apartment = Apartment.objects.create(area=area, location=location, detail=detail, contact=contact, **validated_data) return apartment def validate_floor(self, data): if data < 0: raise serializers.ValidationError("Этаж не может быть отрицательной величиной!!!") return data def validate_storey(self, data): if data < 0: raise serializers.ValidationError("Этажность не может быть отрицательной величиной!!!") return data def validate(self, data): floor = data.get('floor') storey = data.get('storey') area = data.get('area') existing_data = self.to_representation(self.instance) if floor and storey: if data['floor'] > data['storey']: raise serializers.ValidationError("Этаж не должен превышать этажность дома!!!") elif storey: if existing_data['floor'] > data['storey']: raise serializers.ValidationError("Этажность не может быть меньше этажа дома!!!") elif floor: if existing_data['storey'] < data['floor']: raise serializers.ValidationError("Этаж не должен превышать этажность дома!!!") if area: living_area = area.get('living_area') total_area = area.get('total_area') if total_area and living_area: if area['living_area'] > area['total_area']: raise serializers.ValidationError("Жилая площадь не должна быть больше чем общая площадь!!!") elif total_area: if existing_data['area']['living_area'] < area['total_area']: raise serializers.ValidationError("Общая площадь не может быть меньше жилой площади!!!") elif living_area: if existing_data['area']['total_area'] < area['living_area']: raise serializers.ValidationError("Жилая площадь не должна быть больше чем общая площадь!!!") return data def validate_price(self, data): if data < 0: raise serializers.ValidationError("Цена не может " \ "быть отрицательной величиной!!!") return data
class HadithSerializer(AutoTrackSerializer): class Meta: model = Hadith fields = [ 'id', 'text', 'person', 'book', 'tags', 'added_on', 'updated_on', 'added_by', 'updated_by' ] read_only_fields = ['added_on', 'updated_on', 'added_by', 'updated_by'] tags = serializers.ListField(child=serializers.PrimaryKeyRelatedField( queryset=HadithTag.objects.all())) added_on = serializers.DateTimeField(read_only=True, format='%Y-%m-%dT%H:%M:%SZ') updated_on = serializers.DateTimeField(read_only=True, format='%Y-%m-%dT%H:%M:%SZ') def create(self, validated_data): with transaction.atomic(): instance = Hadith() instance.text = validated_data['text'] instance.person = validated_data[ 'person'] if 'person' in validated_data else None instance.book = validated_data[ 'book'] if 'book' in validated_data else None instance.volume = validated_data[ 'volume'] if 'volume' in validated_data else None instance.chapter = validated_data[ 'chapter'] if 'chapter' in validated_data else None instance.section = validated_data[ 'section'] if 'section' in validated_data else None instance.number = validated_data[ 'number'] if 'number' in validated_data else None instance.added_by = self.context['request'].user instance.save() for tag in validated_data['tags']: HadithTagRel.objects.create( hadith=instance, tag=tag, added_by=self.context['request'].user) return instance def update(self, instance, validated_data): with transaction.atomic(): if self.partial: self.__partial_update(instance, validated_data) else: self.__full_update(instance, validated_data) instance.save() return instance def __full_update(self, instance, validated_data): instance.text = validated_data['text'] instance.person = validated_data[ 'person'] if 'person' in validated_data else None instance.book = validated_data[ 'book'] if 'book' in validated_data else None instance.volume = validated_data[ 'volume'] if 'volume' in validated_data else None instance.chapter = validated_data[ 'chapter'] if 'chapter' in validated_data else None instance.section = validated_data[ 'section'] if 'section' in validated_data else None instance.number = validated_data[ 'number'] if 'number' in validated_data else None instance.updated_by = self.context['request'].user # Delete relations for those persons who are not in the updated person list. updated_tag_ids = list(t.id for t in validated_data['tags']) instance.tag_rels.exclude(tag_id__in=updated_tag_ids).delete() tag_ids_to_keep = instance.tag_rels.values_list('tag_id', flat=True) # Make the necessary changes to the existing relations. for tag in [ t for t in validated_data['tags'] if t.id not in tag_ids_to_keep ]: HadithTagRel.objects.create(hadith=instance, tag=tag, added_by=self.context['request'].user) def __partial_update(self, instance, validated_data): if 'text' in validated_data: instance.text = validated_data['text'] if 'person' in validated_data: instance.person = validated_data['person'] if 'book' in validated_data: instance.book = validated_data['book'] if 'volume' in validated_data: instance.volume = validated_data['volume'] if 'chapter' in validated_data: instance.chapter = validated_data['chapter'] if 'section' in validated_data: instance.section = validated_data['section'] if 'number' in validated_data: instance.number = validated_data['number'] instance.updated_by = self.context['request'].user # Delete relations for those persons who are not in the updated person list. if 'tags' in validated_data: updated_tag_ids = list(t.id for t in validated_data['tags']) instance.tag_rels.exclude(tag_id__in=updated_tag_ids).delete() tag_ids_to_keep = instance.tag_rels.values_list('tag_id', flat=True) # Make the necessary changes to the existing relations. for tag in [ t for t in validated_data['tags'] if t.id not in tag_ids_to_keep ]: HadithTagRel.objects.create( hadith=instance, tag=tag, added_by=self.context['request'].user) def to_representation(self, instance): expand = self.context['request'].query_params.get( 'expand', 'false').lower() == 'true' ret = OrderedDict() ret['id'] = instance.id ret['text'] = instance.text ret['book'] = instance.book_id if not expand else \ BookSerializer(instance.book, context=self.context).to_representation(instance.book) ret['volume'] = instance.volume_id if not expand else \ BookVolumeSerializer(instance.volume, context=self.context).to_representation(instance.volume) ret['chapter'] = instance.chapter_id if not expand else \ BookChapterSerializer(instance.chapter, context=self.context).to_representation(instance.chapter) ret['section'] = instance.section_id if not expand else \ BookSectionSerializer(instance.section, context=self.context).to_representation(instance.section) ret['number'] = instance.number if instance.person_id is not None: ret['person'] = instance.person_id if not expand else \ PersonSerializer(instance.person, context=self.context).to_representation(instance.person) else: ret['person'] = None ret['tags'] = instance.tag_rels.values_list('tag_id', flat=True) if not expand \ else [HadithTagSerializer(t.tag, self.context).to_representation(t.tag) for t in instance.tag_rels.all()] ret['added_on'] = instance.added_on ret['updated_on'] = instance.updated_on ret['added_by'] = instance.added_by_id ret['updated_by'] = instance.updated_by_id return ret
class CustomUserSerializer(serializers.ModelSerializer): password = serializers.CharField(style={'input_type': 'password'}, write_only=True, default=None) re_password = serializers.CharField(style={'input_type': 'password'}, write_only=True, default=None) method = MethodSerializer(many=False, read_only=True) method_id = serializers.PrimaryKeyRelatedField( write_only=True, queryset=Method.objects.all(), source='method', default=None) class Meta: model = models.CustomUser fields = ('id', 'username', 'email', 'first_name', 'last_name', 'password', 're_password', 'is_superuser', 'is_active', 'is_principal', 'method', 'method_id', 'role', 'date_joined') # fields = '__all__' def validate(self, data): # user = self.context['request'].user print 'password' print data.get('password') print data.get('re_password') # print user pw = data.get('password') pw2 = data.get('re_password') if pw is not None and pw != pw2: raise serializers.ValidationError('Password must match') return data # def validate_username(self, value, *args, **kwargs): def validate_email(self, value, *args, **kwargs): print 'validate_email - instance' print self.instance username = None if self.instance is not None: username = self.instance.username email = value if email and models.CustomUser.objects.filter(email=email).exclude( username=username).count() > 0: raise serializers.ValidationError( u'This email address is already registered.') return str(email).lower() def validate_is_active(self, value): print 'IS ACTIVE', value superuser = None if self.instance is not None: superuser = self.instance.is_superuser if value is False and superuser: if models.CustomUser.objects.filter(is_superuser=True, is_active=True).count() <= 1: raise serializers.ValidationError( u'Debe existir al menos una cuenta de administrador activa.' ) return value
class UserSerializer(serializers.Serializer): id = serializers.IntegerField(label='ID', read_only=True) password = serializers.CharField(write_only=True, min_length=8, max_length=20) last_login = serializers.DateTimeField(allow_null=True, required=False) is_superuser = serializers.BooleanField( help_text='Designates that this user has all permissions without explicitly assigning them.', label='Superuser status', required=False ) username = serializers.CharField(help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, validators=[UniqueValidator(queryset=User.objects.all())]) first_name = serializers.CharField(max_length=30, required=False) last_name = serializers.CharField(max_length=150, required=False) email = serializers.EmailField(label='Email address', max_length=254, required=False) is_staff = serializers.BooleanField( help_text='Designates whether the user can log into this admin site.', label='Staff status', required=False ) is_active = serializers.BooleanField( help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', label='Active', required=False) date_joined = serializers.DateTimeField(required=False, write_only=True) groups = serializers.PrimaryKeyRelatedField( help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', many=True, queryset=Group.objects.all(), required=False, write_only=True ) group_list = serializers.SerializerMethodField() user_permissions = serializers.PrimaryKeyRelatedField( help_text='Specific permissions for this user.', many=True, queryset=Permission.objects.all(), required=False ) profile = serializers.SerializerMethodField() def get_profile(self, instance): profile = get_or_none(Profile, user=instance) if isinstance(profile, Profile): return {'name': profile.name, 'phone': profile.phone} return {'name': None, 'phone': None} def get_group_list(self, instance): return ','.join(instance.groups.values_list('name', flat=True)) def validate_username(self, attrs): if not validate_username(attrs): raise serializers.ValidationError("Not a valid username") return attrs def validate_password(self, attrs): if isinstance(self.instance, User) and attrs: raise serializers.ValidationError("Password cannot be changed") return attrs def to_representation(self, instance): self.fields["groups"] = GroupSerializer(many=True, read_only=True) self.fields["user_permissions"] = PermissionSerializer(many=True, read_only=True) return super().to_representation(instance=instance) def create(self, validated_data): groups = [] user_permissions = [] if "groups" in validated_data.keys(): groups = validated_data.pop("groups") if "user_permissions" in validated_data.keys(): user_permissions = validated_data.pop("user_permissions") instance = User.objects.create_user(**validated_data) for group in groups: instance.groups.add(group) for user_permission in user_permissions: instance.user_permissions.add(user_permission) return instance def update(self, instance, validated_data): groups = [] user_permissions = [] if "groups" in validated_data.keys(): instance.groups.clear() groups = validated_data.pop("groups") if "user_permissions" in validated_data.keys(): instance.user_permissions.clear() user_permissions = validated_data.pop("user_permissions") User.objects.filter(id=instance.id).update(**validated_data) for group in groups: instance.groups.add(group) for user_permission in user_permissions: instance.user_permissions.add(user_permission) return User.objects.get(id=instance.id)
class PatientConsultationSerializer(serializers.ModelSerializer): id = serializers.CharField(source="external_id", read_only=True) facility_name = serializers.CharField(source="facility.name", read_only=True) suggestion_text = ChoiceField( choices=PatientConsultation.SUGGESTION_CHOICES, read_only=True, source="suggestion", ) symptoms = serializers.MultipleChoiceField(choices=SYMPTOM_CHOICES) category = ChoiceField(choices=CATEGORY_CHOICES, required=False) admitted_to = ChoiceField(choices=ADMIT_CHOICES, required=False) referred_to_object = FacilityBasicInfoSerializer(source="referred_to", read_only=True) referred_to = ExternalIdSerializerField(queryset=Facility.objects.all(), required=False) patient = ExternalIdSerializerField( queryset=PatientRegistration.objects.all()) facility = ExternalIdSerializerField(queryset=Facility.objects.all()) assigned_to_object = UserBaseMinimumSerializer(source="assigned_to", read_only=True) assigned_to = serializers.PrimaryKeyRelatedField( queryset=User.objects.all(), required=False, allow_null=True) action = ChoiceField(choices=PatientRegistration.ActionChoices, write_only=True, required=False) review_time = serializers.IntegerField(default=-1, write_only=True, required=False) last_edited_by = UserBaseMinimumSerializer(read_only=True) created_by = UserBaseMinimumSerializer(read_only=True) class Meta: model = PatientConsultation read_only_fields = TIMESTAMP_FIELDS + ( "last_updated_by_telemedicine", "discharge_date", "last_edited_by", "created_by", "kasp_enabled_date", ) exclude = ("deleted", "external_id") def validate_bed_number(self, bed_number): try: if not self.initial_data["admitted"]: bed_number = None except KeyError: bed_number = None return bed_number def update(self, instance, validated_data): instance.last_edited_by = self.context["request"].user if instance.discharge_date: raise ValidationError({ "consultation": ["Discharged Consultation data cannot be updated"] }) if instance.suggestion == SuggestionChoices.OP: instance.discharge_date = localtime(now()) instance.save() if "action" in validated_data or "review_time" in validated_data: patient = instance.patient if "action" in validated_data: action = validated_data.pop("action") patient.action = action if "review_time" in validated_data: review_time = validated_data.pop("review_time") if review_time >= 0: patient.review_time = localtime( now()) + timedelta(minutes=review_time) patient.save() validated_data["last_updated_by_telemedicine"] = self.context[ "request"].user == instance.assigned_to if "is_kasp" in validated_data: if validated_data["is_kasp"] and (not instance.is_kasp): validated_data["kasp_enabled_date"] = localtime(now()) if "assigned_to" in validated_data: if validated_data["assigned_to"] != instance.assigned_to: NotificationGenerator( event=Notification.Event.PATIENT_CONSULTATION_ASSIGNMENT, caused_by=self.context["request"].user, caused_object=instance, facility=instance.patient.facility, notification_mediums=[ Notification.Medium.SYSTEM, Notification.Medium.WHATSAPP ], ).generate() consultation = super().update(instance, validated_data) NotificationGenerator( event=Notification.Event.PATIENT_CONSULTATION_UPDATED, caused_by=self.context["request"].user, caused_object=consultation, facility=consultation.patient.facility, ).generate() return consultation def create(self, validated_data): action = -1 review_time = -1 if "action" in validated_data: action = validated_data.pop("action") if "review_time" in validated_data: review_time = validated_data.pop("review_time") if validated_data["patient"].last_consultation: if self.context["request"].user == validated_data[ "patient"].last_consultation.assigned_to: raise ValidationError( { "Permission Denied": "Only Facility Staff can create consultation for a Patient" }, ) if validated_data["patient"].last_consultation: if not validated_data["patient"].last_consultation.discharge_date: raise ValidationError({ "consultation": "Exists please Edit Existing Consultation" }) if "is_kasp" in validated_data: if validated_data["is_kasp"]: validated_data["kasp_enabled_date"] = localtime(now()) consultation = super().create(validated_data) consultation.created_by = self.context["request"].user consultation.last_edited_by = self.context["request"].user consultation.save() patient = consultation.patient if consultation.suggestion == SuggestionChoices.OP: consultation.discharge_date = localtime(now()) consultation.save() patient.is_active = False patient.allow_transfer = True patient.last_consultation = consultation if action != -1: patient.action = action if review_time > 0: patient.review_time = localtime( now()) + timedelta(minutes=review_time) patient.save() NotificationGenerator( event=Notification.Event.PATIENT_CONSULTATION_CREATED, caused_by=self.context["request"].user, caused_object=consultation, facility=patient.facility, ).generate() if consultation.assigned_to: NotificationGenerator( event=Notification.Event.PATIENT_CONSULTATION_ASSIGNMENT, caused_by=self.context["request"].user, caused_object=consultation, facility=consultation.patient.facility, notification_mediums=[ Notification.Medium.SYSTEM, Notification.Medium.WHATSAPP ], ).generate() return consultation def validate(self, obj): validated = super().validate(obj) if validated["suggestion"] is SuggestionChoices.R and not validated.get( "referred_to"): raise ValidationError({ "referred_to": [ f"This field is required as the suggestion is {SuggestionChoices.R}." ] }) if (validated["suggestion"] is SuggestionChoices.A and validated.get("admitted") and not validated.get("admission_date")): raise ValidationError({ "admission_date": [f"This field is required as the patient has been admitted."] }) if "action" in validated: if validated["action"] == PatientRegistration.ActionEnum.REVIEW: if "review_time" not in validated: raise ValidationError({ "review_time": [ f"This field is required as the patient has been requested Review." ] }) if validated["review_time"] <= 0: raise ValidationError({ "review_time": [f"This field value is must be greater than 0."] }) return validated
class PatientConsultationSerializer(serializers.ModelSerializer): id = serializers.CharField(source="external_id", read_only=True) facility_name = serializers.CharField(source="facility.name", read_only=True) suggestion_text = ChoiceField( choices=PatientConsultation.SUGGESTION_CHOICES, read_only=True, source="suggestion") symptoms = serializers.MultipleChoiceField(choices=SYMPTOM_CHOICES) category = ChoiceField(choices=CATEGORY_CHOICES, required=False) admitted_to = ChoiceField(choices=ADMIT_CHOICES, required=False) referred_to_object = FacilityBasicInfoSerializer(source="referred_to", read_only=True) referred_to = ExternalIdSerializerField(queryset=Facility.objects.all(), required=False) patient = ExternalIdSerializerField( queryset=PatientRegistration.objects.all()) facility = ExternalIdSerializerField(queryset=Facility.objects.all()) assigned_to_object = UserBaseMinimumSerializer(source="assigned_to", read_only=True) assigned_to = serializers.PrimaryKeyRelatedField( queryset=User.objects.all(), required=False, allow_null=True) action = ChoiceField(choices=PatientRegistration.ActionChoices, write_only=True, required=False) review_time = serializers.IntegerField(default=-1, write_only=True, required=False) last_edited_by = UserBaseMinimumSerializer(read_only=True) created_by = UserBaseMinimumSerializer(read_only=True) class Meta: model = PatientConsultation read_only = TIMESTAMP_FIELDS + ("discharge_date", "last_edited_by", "created_by") exclude = ("deleted", "external_id") def validate_bed_number(self, bed_number): try: if not self.initial_data["admitted"]: bed_number = None except KeyError: bed_number = None return bed_number def update(self, instance, validated_data): instance.last_edited_by = self.context["request"].user if instance.discharge_date: raise ValidationError({ "consultation": [f"Discharged Consultation data cannot be updated"] }) if instance.suggestion == SuggestionChoices.OP: instance.discharge_date = localtime(now()) instance.save() if "action" in validated_data or "review_time" in validated_data: patient = instance.patient if "action" in validated_data: action = validated_data.pop("action") patient.action = action if "review_time" in validated_data: review_time = validated_data.pop("review_time") if review_time >= 0: patient.review_time = localtime( now()) + timedelta(minutes=review_time) patient.save() return super().update(instance, validated_data) def create(self, validated_data): action = -1 review_time = -1 if "action" in validated_data: action = validated_data.pop("action") if "review_time" in validated_data: review_time = validated_data.pop("review_time") consultation = super().create(validated_data) consultation.created_by = self.context["request"].user consultation.last_edited_by = self.context["request"].user consultation.save() patient = consultation.patient if consultation.suggestion == SuggestionChoices.OP: consultation.discharge_date = localtime(now()) consultation.save() patient.is_active = False patient.allow_transfer = True patient.last_consultation = consultation if action != -1: patient.action = action if review_time > 0: patient.review_time = localtime( now()) + timedelta(minutes=review_time) patient.save() return consultation def validate(self, obj): validated = super().validate(obj) if validated["suggestion"] is SuggestionChoices.R and not validated.get( "referred_to"): raise ValidationError({ "referred_to": [ f"This field is required as the suggestion is {SuggestionChoices.R}." ] }) if (validated["suggestion"] is SuggestionChoices.A and validated.get("admitted") and not validated.get("admission_date")): raise ValidationError({ "admission_date": [f"This field is required as the patient has been admitted."] }) if "action" in validated: if validated["action"] == PatientRegistration.ActionEnum.REVIEW: if "review_time" not in validated: raise ValidationError({ "review_time": [ f"This field is required as the patient has been requested Review." ] }) if validated["review_time"] <= 0: raise ValidationError({ "review_time": [f"This field value is must be greater than 0."] }) return validated
class CreateEventSerializer(serializers.ModelSerializer): tags = serializers.PrimaryKeyRelatedField(queryset=Tag.objects.all(), many=True) event_logistics = serializers.ListField( child=serializers.DictField( child=serializers.CharField(required=False) ), required=False, write_only=True ) hosts = serializers.ListField( child=serializers.IntegerField(), required=False, write_only=True ) def validate_hosts(self, hosts): for host in hosts: if not OrgHost.objects.filter(pk=host).exists() and not SangguHost.objects.filter(pk=host).exists() and not OfficeHost.objects.filter(pk=host).exists(): raise serializers.ValidationError("Host with index {} does not exist".format(host)) return hosts def validate_event_logistics(self, logistics): for logistic in logistics: try: datetime.strptime(logistic['date'], "%Y-%m-%d") except ValueError: raise serializers.ValidationError("Date is not valid") try: time.strptime(logistic['start_time'], "%H:%M:%S") except ValueError: raise serializers.ValidationError("Start time is not valid") try: time.strptime(logistic['end_time'], "%H:%M:%S") except ValueError: raise serializers.ValidationError("End time is not valid") if 'venue' in logistic and not Venue.objects.filter(pk=int(logistic['venue'])).exists(): raise serializers.ValidationError("Venue does not exist") return logistics def create(self, validated_data): return save_event(validated_data, None) def update(self, instance, validated_data): return save_event(validated_data, instance) class Meta: model = Event fields = ['id', 'name', 'hosts', 'sanggu_hosts', 'office_hosts', 'org_hosts', 'description', 'poster_url', 'event_url', 'tags', 'audience', 'event_logistics']
class OngoingWorkOrderCompletionSurveyOperationSerializer(serializers.Serializer): ongoing_job = serializers.PrimaryKeyRelatedField(many=False, queryset=OngoingWorkOrder.objects.all(), required=True) reason = serializers.CharField(required=True, allow_blank=False) # Meta Information. class Meta: fields = ( 'ongoing_job', 'reason', ) # def validate(self, data): # """ # Override the validator to provide additional custom validation based # on our custom logic. # # 1. If 'reason' == 1 then make sure 'reason_other' was inputted. # """ # # CASE 1 - Other reason # if data['reason'] == 1: # reason_other = data['reason_other'] # if reason_other == "": # raise serializers.ValidationError(_("Please provide a reason as to why you chose the \"Other\" option.")) # return data # Return our data. def create(self, validated_data): """ Override the `create` function to add extra functinality. """ #-------------------------# # Get validated POST data # #-------------------------# ongoing_job = validated_data.get('ongoing_job', None) reason = validated_data.get('reason', None) #------------------------------------------# # Create any additional optional comments. # #------------------------------------------# comment_obj = Comment.objects.create( created_by=self.context['user'], last_modified_by=self.context['user'], text=reason, created_from = self.context['from'], created_from_is_public = self.context['from_is_public'] ) OngoingWorkOrderComment.objects.create( about=ongoing_job, comment=comment_obj, ) # For debugging purposes only. logger.info("Job comment created.") #-------------------------# # Update the ongoing ongoing_job. # #-------------------------# ongoing_job.state = ONGOING_WORK_ORDER_STATE.RUNNING ongoing_job.latest_pending_task = None ongoing_job.save() # For debugging purposes only. logger.info("Updated ongoing ongoing job.") #---------------------------------# # Close all the TaskItem objects. # #---------------------------------# for task_item in TaskItem.objects.filter(ongoing_job=ongoing_job, is_closed=False): task_item.last_modified_by = self.context['user'] task_item.last_modified_from = self.context['from'] task_item.last_modified_from_is_public = self.context['from_is_public'] task_item.is_closed = True task_item.closing_reason = 1 # (Other - choice.) task_item.closing_reason_other = 'Closed because master ongoing job was closed.' task_item.save() # Return our processed values. return validated_data
class CreatorSerializer(serializers.ModelSerializer): last_name = serializers.CharField( allow_blank=False, max_length=45 ) first_name = serializers.CharField( allow_blank=False ) display_name = serializers.CharField( allow_blank=True, max_length=100 ) attribution = AttributionSerializer( source='attribution_set', # Note use of _set many=True, read_only=True ) attribution_ids = serializers.PrimaryKeyRelatedField( many=True, write_only=True, queryset=Book.objects.all(), source='attribution' ) class Meta: model = Creator fields = ( 'last_name', 'first_name', 'display_name', 'attribution', 'attribution_ids' ) def create(self, validated_data): """ This method persists a new HeritageSite instance as well as adds all related countries/areas to the heritage_site_jurisdiction table. It does so by first removing (validated_data.pop('heritage_site_jurisdiction')) from the validated data before the new HeritageSite instance is saved to the database. It then loops over the heritage_site_jurisdiction array in order to extract each country_area_id element and add entries to junction/associative heritage_site_jurisdiction table. :param validated_data: :return: site """ # print(validated_data) books = validated_data.pop('attribution') creator = Creator.objects.create(**validated_data) if books is not None: for book in books: Attribution.objects.create( creator_id=creator.creator_id, book_id=book.book_id, role_id=None # Not worrying about this right now, may return to it later. ) return creator def update(self, instance, validated_data): creator_id = instance.creator_id new_books = validated_data.pop('attribution') instance.last_name = validated_data.get( 'last_name', instance.last_name ) instance.first_name = validated_data.get( 'first_name', instance.first_name ) instance.display_name = validated_data.get( 'display_name', instance.display_name ) instance.save() # If any existing books are not in updated list, delete them new_ids = [] old_ids = Attribution.objects \ .values_list('book_id', flat=True) \ .filter(creator_id__exact=creator_id) # TODO Insert may not be required (Just return instance) # Insert new unmatched book entries for book in new_books: new_id = book.book_id new_ids.append(new_id) if new_id in old_ids: continue else: Attribution.objects \ .create(creator_id=creator_id, book_id=new_id, role_id=None) # Delete old unmatched book entries for old_id in old_ids: if old_id in new_ids: continue else: Attribution.objects \ .filter(creator_id=creator_id, book_id=old_id) \ .delete() return instance
class SampleSerializer(serializers.Serializer): addon = SplitField( serializers.PrimaryKeyRelatedField(queryset=Addon.objects), AddonSerializer())
class CrewMemberRequestSerializer(serializers.ModelSerializer): user = UserSerializer(read_only=True) role = RoleSerializer(read_only=True) requestor = UserSerializer(read_only=True) movie_title = serializers.CharField(source="movie.title", read_only=True) # write only name = serializers.CharField(write_only=True) email = serializers.EmailField(write_only=True) roles = serializers.PrimaryKeyRelatedField( queryset=Role.objects.all(), many=True, write_only=True ) class Meta: model = CrewMemberRequest fields = [ "id", "name", "email", "roles", "movie", "requestor", "user", "role", "movie_title", "state", ] read_only_fields = [ "id", "requestor", "role", "user", "movie_title", ] def _create_new_user(self, name, email): email = email.strip().lower() name_segs = [seg.strip() for seg in name.split(" ")] first_name = name_segs[0] last_name = " ".join(name_segs[1:]) try: user = User.objects.get(email=email) except User.DoesNotExist: user = User.objects.create_user( first_name=first_name, last_name=last_name, username=email, email=email, ) return user def create(self, validated_data): requestor = validated_data.pop("logged_in_user") movie = validated_data.get("movie") validated_data["requestor"] = requestor email = validated_data.pop("email") name = validated_data.pop("name") instance = None director = Role.objects.get(name="Director") requestor_is_director_of_movie = CrewMember.objects.filter( profile__user=requestor, role=director, movie=movie ).exists() state = ( CREW_MEMBER_REQUEST_STATE.APPROVED if requestor_is_director_of_movie else CREW_MEMBER_REQUEST_STATE.SUBMITTED ) with transaction.atomic(): user = self._create_new_user(name, email) validated_data["user"] = user for role in validated_data.pop("roles"): validated_data["role"] = role instance = CrewMemberRequest.objects.create( **validated_data, state=state ) return instance
class CreateOrderSerializer(OrderPackageValidateMixin, serializers.ModelSerializer): movie = serializers.PrimaryKeyRelatedField( queryset=Movie.objects.all(), write_only=True, required=True ) class Meta: model = Order fields = [ "id", "owner", "order_id", "amount", "payment_id", "package", "state", "movie", ] read_only_fields = [ "id", "owner", "order_id", "amount", "payment_id", "state", ] def validate_movie(self, movie): request = self.context.get("request") if not movie.orders.filter(owner=request.user).exists(): logger.warn("User is not person who submitted the movie") raise serializers.ValidationError( "You cannot create and Order for this Movie" ) return movie def validate(self, data): package = data["package"] movie = data.get("movie") if movie: pending_order_same_package = movie.orders.filter( package=package, state=ORDER_STATE.CREATED ) if pending_order_same_package.exists(): raise serializers.ValidationError( "An order already exists for this movie with this package" ) return data def create(self, validated_data): # Scenario: when used selected a package then moved to payment step, then came back and selected a different package # then we need to create a new order with the already existing movie # expecting, user, movie, package logger.debug(f"create_order::{validated_data}") user = validated_data.pop("user", None) movie = validated_data.pop("movie", None) package = validated_data.get("package") rzp_order = create_rzp_order(package, user) validated_data["owner"] = user validated_data["order_id"] = rzp_order.get("id") validated_data["amount"] = rzp_order.get("amount") validated_data["receipt_number"] = rzp_order.get("receipt") order = super().create(validated_data) order.movies.add(movie) return order
class CourseLessonSerializer(serializers.ModelSerializer): courses = serializers.PrimaryKeyRelatedField(many=True) class Meta: model = Lesson
class UserSerializer(serializers.ModelSerializer): thrives = serializers.PrimaryKeyRelatedField(many=True, read_only=True) class Meta: model = User fields = ('url', 'username', 'email', 'is_staff', 'thrives')
class CitySerializer(serializers.ModelSerializer): country = serializers.PrimaryKeyRelatedField(read_only=True) class Meta: model = City fields = ('id', 'name', 'country')
class ProductsForOrderSerializer(serializers.Serializer): product_id = serializers.PrimaryKeyRelatedField(queryset=Product.objects.all(), source="product.id") title = serializers.CharField(source='product.title', read_only=True) price = serializers.DecimalField(max_digits=9, decimal_places=2, source='product.price', read_only=True) amount = serializers.IntegerField(min_value=1, max_value=10)
class RecipeSerializer(serializers.ModelSerializer): author = serializers.HiddenField(default=serializers.CurrentUserDefault()) author_full_name = serializers.SerializerMethodField() author_username = serializers.SerializerMethodField() recipe_image = RecipeImageSerializer(many=False, read_only=True) category_set = CategorySerializer(many=True, required=False) variant_of = serializers.PrimaryKeyRelatedField( many=False, queryset=Recipe.objects.all(), required=False, allow_null=True) variant = serializers.SerializerMethodField() class Meta: model = Recipe fields = [ "id", "title", "slug", "portions", "instructions", "inspiration", "author", "author_full_name", "author_username", "creation_date", "update_date", "recipe_image", "logical_delete", "category_set", "variant_of", "variant" ] read_only_fields = ("slug", "recipe_image") def get_variant(self, instance): return Recipe.objects.filter(id=instance.id) \ .filter(Q(variant__logical_delete=False) & Q(variant__isnull=False)) \ .values_list('variant', flat=True) def get_author_full_name(self, instance): if (instance.author): return str(instance.author.first_name + " " + instance.author.last_name) else: return None def get_author_username(self, instance): if (instance.author): return str(instance.author.username) else: return None def validate_variant_of(self, value): if self.initial_data.get('id') and self.initial_data.get( 'id') == value.id: raise serializers.ValidationError( gettext("The recipe can't be a variant of itself.")) return value def validate_category_set(self, value): if value is not None and len(value) > 0: all_categories = list(Category.objects.all()) result_categories_list = [] # Retourner un tableau avec l'ensemble des Objets category qui correspondent aux id et aux nom des json présent dans le tableau value for category in value: # Permet d'avoir l'objet qui correspond exactement au json object_category = next( (x for x in all_categories if x.name == category['name']), None) if object_category: result_categories_list.append(object_category) else: raise serializers.ValidationError( gettext( "The {category_name} category is not a valid one." ).format(category_name=category.name)) return result_categories_list else: return [] def update(self, instance, validated_data): category_data = validated_data.pop('category_set') instance.category_set.clear() for category in category_data: instance.category_set.add(category) return super().update(instance, validated_data) def create(self, validated_data): category_data = validated_data.pop('category_set', []) newRecipe = Recipe.objects.create(**validated_data) for category in category_data: newRecipe.category_set.add(category) return newRecipe
def to_internal_value(self, data): self.fields['plan'] = serializers.PrimaryKeyRelatedField(queryset=models.SubscriptionPlan.objects.all()) return super(PlanListDetailSerializer, self).to_internal_value(data)
class PlaceSerializer(SubmittedThingSerializer, serializers.HyperlinkedModelSerializer): url = PlaceIdentityField() id = serializers.PrimaryKeyRelatedField(read_only=True) geometry = GeometryField(format='wkt') dataset = DataSetRelatedField() attachments = AttachmentSerializer(read_only=True, many=True) submitter = UserSerializer(read_only=False) class Meta: model = models.Place def get_submission_sets(self, place): include_invisible = self.is_flag_on(INCLUDE_INVISIBLE_PARAM) submission_sets = defaultdict(list) for submission in place.submissions.all(): if include_invisible or submission.visible: set_name = submission.set_name submission_sets[set_name].append(submission) return submission_sets def get_submission_set_summaries(self, place): """ Get a mapping from place id to a submission set summary dictionary. Get this for the entire dataset at once. """ request = self.context['request'] submission_sets = self.get_submission_sets(place) summaries = {} for set_name, submissions in submission_sets.iteritems(): # Ensure the user has read permission on the submission set. user = getattr(request, 'user', None) client = getattr(request, 'client', None) dataset = getattr(request, 'get_dataset', lambda: None)() if not check_data_permission(user, client, 'retrieve', dataset, set_name): continue url_field = SubmissionSetIdentityField() url_field.initialize(parent=self, field_name=None) set_url = url_field.field_to_native(submissions[0], None) summaries[set_name] = { 'name': set_name, 'length': len(submissions), 'url': set_url, } return summaries def get_detailed_submission_sets(self, place): """ Get a mapping from place id to a detiled submission set dictionary. Get this for the entire dataset at once. """ request = self.context['request'] submission_sets = self.get_submission_sets(place) details = {} for set_name, submissions in submission_sets.iteritems(): # Ensure the user has read permission on the submission set. user = getattr(request, 'user', None) client = getattr(request, 'client', None) dataset = getattr(request, 'get_dataset', lambda: None)() if not check_data_permission(user, client, 'retrieve', dataset, set_name): continue # We know that the submission datasets will be the same as the place # dataset, so say so and avoid an extra query for each. for submission in submissions: submission.dataset = place.dataset serializer = SubmissionSerializer(submissions, many=True) serializer.initialize(parent=self, field_name=None) details[set_name] = serializer.data return details def to_native(self, obj): obj = self.ensure_obj(obj) fields = self.get_fields() data = { 'url': fields['url'].field_to_native(obj, 'pk'), # = PlaceIdentityField() 'id': obj.pk, # = serializers.PrimaryKeyRelatedField(read_only=True) 'geometry': str(obj.geometry or 'POINT(0 0)'), # = GeometryField(format='wkt') 'dataset': obj.dataset_id, # = DataSetRelatedField() 'attachments': [AttachmentSerializer(a).data for a in obj.attachments.all() ], # = AttachmentSerializer(read_only=True) 'submitter': UserSerializer(obj.submitter).data if obj.submitter else None, 'data': obj.data, 'visible': obj.visible, 'created_datetime': obj.created_datetime.isoformat() if obj.created_datetime else None, 'updated_datetime': obj.updated_datetime.isoformat() if obj.updated_datetime else None, } data = self.explode_data_blob(data) # data = super(PlaceSerializer, self).to_native(obj) # TODO: Put this flag value directly in to the serializer context, # instead of relying on the request query parameters. if not self.is_flag_on(INCLUDE_SUBMISSIONS_PARAM): submission_sets_getter = self.get_submission_set_summaries else: submission_sets_getter = self.get_detailed_submission_sets data['submission_sets'] = submission_sets_getter(obj) if hasattr(obj, 'distance'): data['distance'] = str(obj.distance) return data
class SubmissionMetaTermsSerializer(serializers.Serializer): meta_terms = serializers.PrimaryKeyRelatedField(many=True, queryset=MetaTerm.objects.all())
class ChainSerializer(serializers.ModelSerializer): """ A serializer for chains which makes it easy to retrieve or update the persons in the chain as if they were an array inside the chains table. The serializer takes the persons array and creates the necessary relations between chains and persons. In case of updating an existing chain, it will find the changes that need to be made to the existing links and make the necessary creations and deletion for the end result to match what the user sends. """ class Meta: model = Chain fields = [ 'id', 'hadith', 'persons', 'added_on', 'updated_on', 'added_by', 'updated_by' ] read_only_fields = ['added_on', 'updated_on', 'added_by', 'updated_by'] persons = serializers.ListField(child=serializers.PrimaryKeyRelatedField( queryset=Person.objects.all())) added_on = serializers.DateTimeField(read_only=True, format='%Y-%m-%dT%H:%M:%SZ') updated_on = serializers.DateTimeField(read_only=True, format='%Y-%m-%dT%H:%M:%SZ') def create(self, validated_data): with transaction.atomic(): instance = Chain() instance.hadith = validated_data['hadith'] instance.added_by = self.context['request'].user instance.save() for i, person in enumerate(validated_data['persons']): rel = ChainPersonRel(chain=instance, person=person, order=i + 1) rel.save() return instance def update(self, instance, validated_data): with transaction.atomic(): # TODO: Do we want to enable changing the hadith a certain chain is # attached to? Does this have a valid use case? instance.hadith = validated_data['hadith'] instance.updated_by = self.context['request'].user # Delete relations for those persons who are not in the updated person list. updated_person_ids = list(p.id for p in validated_data['persons']) instance.person_rels.exclude( person_id__in=updated_person_ids).delete() # Make the necessary changes to the existing relations. for i, person in enumerate(validated_data['persons']): rel = ChainPersonRel.objects.filter(chain=instance, person=person).first() if rel is None: ChainPersonRel.objects.create(chain=instance, person=person, order=i + 1) elif rel.order != i + 1: rel.order = i + 1 rel.save() instance.save() return instance def validate_persons(self, persons): person_ids = [p.id for p in persons] rep_ids = [id for id, cnt in Counter(person_ids).items() if cnt > 1] if rep_ids: raise serializers.ValidationError( 'The same person cannot appear twice in a chain. The following ID(s) ' 'appeared more than once in the chain: ' + ', '.join(map(str, rep_ids))) return persons def to_representation(self, instance): expand = self.context['request'].query_params.get( 'expand', 'false').lower() == 'true' ret = OrderedDict() ret['id'] = instance.id ret['hadith'] = instance.hadith_id if not expand else \ HadithSerializer(instance.hadith, context=self.context).to_representation(instance.hadith) ret['persons'] = instance.person_rels.values_list('person_id', flat=True).order_by('order') if not expand \ else [PersonSerializer(p.person, context=self.context).to_representation(p.person) for p in instance.person_rels.order_by('order').all()] ret['added_on'] = instance.added_on ret['updated_on'] = instance.updated_on ret['added_by'] = instance.added_by_id ret['updated_by'] = instance.updated_by_id return ret
class ArtworkSerializer(serializers.ModelSerializer): artwork_name = serializers.CharField(allow_blank=False, max_length=999) accession_number = serializers.CharField(allow_blank=False, max_length=6) date_text = serializers.CharField(allow_blank=True) medium = serializers.CharField(allow_null=True) credit_line = serializers.CharField(allow_null=True) acquisition_year = serializers.IntegerField(allow_null=False) width = serializers.IntegerField(allow_null=True, ) height = serializers.IntegerField(allow_null=True, ) depth = serializers.IntegerField(allow_null=True, ) artist = ArtistSerializer(many=False, read_only=True) artist_id = serializers.PrimaryKeyRelatedField( allow_null=False, many=False, write_only=True, queryset=Artist.objects.all(), source='artist') artist_role = ArtistRoleSerializer(many=False, read_only=True) artist_role_id = serializers.PrimaryKeyRelatedField( allow_null=False, many=False, write_only=True, queryset=ArtistRole.objects.all(), source='artist_role') artwork_subject = ArtworkSubjectSerializer( source='artwork_subject_set', # Note use of _set many=True, read_only=True) subject_ids = serializers.PrimaryKeyRelatedField( many=True, write_only=True, queryset=Subject.objects.all(), source='artwork_subject') class Meta: model = Artwork fields = ('artwork_id', 'artwork_name', 'accession_number', 'date_text', 'medium', 'credit_line', 'acquisition_year', 'width', 'height', 'depth', 'artist', 'artist_id', 'artist_role', 'artist_role_id', 'artwork_subject', 'subject_ids') def create(self, validated_data): """ :param validated_data: :return: artwork """ # print(validated_data) subjects = validated_data.pop('artwork_subject') artwork = Artwork.objects.create(**validated_data) if subjects is not None: for subject in subjects: ArtworkSubject.objects.create(artwork_id=artwork.artwork_id, subject_id=subject.subject_id) return artwork def update(self, instance, validated_data): artwork_id = instance.artwork_id new_subjects = validated_data.pop('artwork_subject') instance.artwork_name = validated_data.get('artwork_name', instance.artwork_name) instance.accession_number = validated_data.get( 'accession_number', instance.accession_number) instance.date_text = validated_data.get('date_text', instance.date_text) instance.medium = validated_data.get('medium', instance.medium) instance.credit_line = validated_data.get('credit_line', instance.credit_line) instance.acquisition_year = validated_data.get( 'acquisition_year', instance.acquisition_year) instance.width = validated_data.get('width', instance.width) instance.height = validated_data.get('height', instance.height) instance.depth = validated_data.get('depth', instance.depth) instance.artist_id = validated_data.get('artist', instance.artist_id).artist_id instance.artist_role_id = validated_data.get( 'artist_role', instance.artist_role_id).artist_role_id instance.save() # If any existing subjects are not in updated list, delete them new_ids = [] old_ids = ArtworkSubject.objects \ .values_list('subject_id', flat=True) \ .filter(artwork_id__exact=artwork_id) # TODO Insert may not be required (Just return instance) # Insert new unmatched subject entries for subject in new_subjects: new_id = subject.subject_id new_ids.append(new_id) if new_id in old_ids: continue else: ArtworkSubject.objects \ .create(artwork_id=artwork_id, subject_id=new_id) # Delete old unmatched subject entries for old_id in old_ids: if old_id in new_ids: continue else: ArtworkSubject.objects \ .filter(artwork_id=artwork_id, subject_id=old_id) \ .delete() return instance
class UserSerializer(serializers.ModelSerializer): recipe = serializers.PrimaryKeyRelatedField(many=True, queryset=Recipe.objects.all()) class Meta: model = User fields = ['id', 'username', 'recipe']
class TagSerializer(serializers.ModelSerializer): article__count = serializers.IntegerField(read_only=True) article_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True) class Meta: model=Tag fields =['id','name','article__count','article_set']
def getHumanReadableName(self, obj): return str(obj) def getValidators(self, obj): try: return obj.getValidators() except: return None class Meta: model = {{ object.camel }} fields = ('humanReadableName', 'validators', {% for prop in object.props %}'{{ prop }}',{% endfor %}{% for ref in object.refs %}{%if ref.multi %}'{{ ref.plural }}'{% else %}'{{ ref }}'{% endif %},{% endfor %}) class {{ object.camel }}IdSerializer(XOSModelSerializer): id = IdField() {% for ref in object.refs %} {% if ref.multi %} {{ ref.plural }} = serializers.PrimaryKeyRelatedField(many=True, queryset = {{ ref.camel }}.objects.all()) {% else %} {{ ref }} = serializers.PrimaryKeyRelatedField( queryset = {{ ref.camel }}.objects.all()) {% endif %} {% endfor %} humanReadableName = serializers.SerializerMethodField("getHumanReadableName") validators = serializers.SerializerMethodField("getValidators") def getHumanReadableName(self, obj): return str(obj) def getValidators(self, obj): try: return obj.getValidators() except: return None class Meta: model = {{ object.camel }}
class CourseSerializer(serializers.ModelSerializer): teachers = serializers.PrimaryKeyRelatedField(many=True) students = serializers.PrimaryKeyRelatedField(many=True) class Meta: model = Course
class ChangeApartmentImageSerializer(serializers.ModelSerializer): apartment = serializers.PrimaryKeyRelatedField(read_only=True) class Meta: model = ApartmentImage fields = ('id', 'apartment', 'image',)
class HeritageSiteSerializer(serializers.ModelSerializer): site_name = serializers.CharField(allow_blank=False, max_length=255) description = serializers.CharField(allow_blank=False) justification = serializers.CharField(allow_blank=True) date_inscribed = serializers.IntegerField(allow_null=True) longitude = serializers.DecimalField(allow_null=True, max_digits=11, decimal_places=8) latitude = serializers.DecimalField(allow_null=True, max_digits=10, decimal_places=8) area_hectares = serializers.FloatField(allow_null=True) transboundary = serializers.IntegerField(allow_null=False) heritage_site_category = HeritageSiteCategorySerializer(many=False, read_only=True) heritage_site_category_id = serializers.PrimaryKeyRelatedField( allow_null=False, many=False, write_only=True, queryset=HeritageSiteCategory.objects.all(), source='heritage_site_category') heritage_site_jurisdiction = HeritageSiteJurisdictionSerializer( source='heritage_site_jurisdiction_set', # Note use of _set many=True, read_only=True) jurisdiction_ids = serializers.PrimaryKeyRelatedField( many=True, write_only=True, queryset=CountryArea.objects.all(), source='heritage_site_jurisdiction') class Meta: model = HeritageSite fields = ('heritage_site_id', 'site_name', 'description', 'justification', 'date_inscribed', 'longitude', 'latitude', 'area_hectares', 'transboundary', 'heritage_site_category', 'heritage_site_category_id', 'heritage_site_jurisdiction', 'jurisdiction_ids') def create(self, validated_data): """ This method persists a new HeritageSite instance as well as adds all related countries/areas to the heritage_site_jurisdiction table. It does so by first removing (validated_data.pop('heritage_site_jurisdiction')) from the validated data before the new HeritageSite instance is saved to the database. It then loops over the heritage_site_jurisdiction array in order to extract each country_area_id element and add entries to junction/associative heritage_site_jurisdiction table. :param validated_data: :return: site """ # print(validated_data) countries = validated_data.pop('heritage_site_jurisdiction') site = HeritageSite.objects.create(**validated_data) if countries is not None: for country in countries: HeritageSiteJurisdiction.objects.create( heritage_site_id=site.heritage_site_id, country_area_id=country.country_area_id) return site def update(self, instance, validated_data): # site_id = validated_data.pop('heritage_site_id') site_id = instance.heritage_site_id new_countries = validated_data.pop('heritage_site_jurisdiction') instance.site_name = validated_data.get('site_name', instance.site_name) instance.description = validated_data.get('description', instance.description) instance.justification = validated_data.get('justification', instance.justification) instance.date_inscribed = validated_data.get('date_inscribed', instance.date_inscribed) instance.longitude = validated_data.get('longitude', instance.longitude) instance.latitude = validated_data.get('latitude', instance.latitude) instance.area_hectares = validated_data.get('area_hectares', instance.area_hectares) instance.heritage_site_category_id = validated_data.get( 'heritage_site_category_id', instance.heritage_site_category_id) instance.transboundary = validated_data.get('transboundary', instance.transboundary) instance.save() # If any existing country/areas are not in updated list, delete them new_ids = [] old_ids = HeritageSiteJurisdiction.objects \ .values_list('country_area_id', flat=True) \ .filter(heritage_site_id__exact=site_id) # TODO Insert may not be required (Just return instance) # Insert new unmatched country entries for country in new_countries: new_id = country.country_area_id new_ids.append(new_id) if new_id in old_ids: continue else: HeritageSiteJurisdiction.objects \ .create(heritage_site_id=site_id, country_area_id=new_id) # Delete old unmatched country entries for old_id in old_ids: if old_id in new_ids: continue else: HeritageSiteJurisdiction.objects \ .filter(heritage_site_id=site_id, country_area_id=old_id) \ .delete() return instance