def as_serializer_error(exc): assert isinstance(exc, (ValidationError, DjangoValidationError)) if isinstance(exc, DjangoValidationError): detail = get_error_detail(exc) else: detail = exc.detail if isinstance(detail, Mapping): # If errors may be a dict we use the standard # {key: list of values}. Here we ensure that all the values are # *lists* of errors. return { key: value if isinstance(value, (list, Mapping)) else [value] for key, value in detail.items() } elif isinstance(detail, list): # Errors raised as a list are non-field errors. return { api_settings.NON_FIELD_ERRORS_KEY: detail } # Errors raised as a string are non-field errors. return { api_settings.NON_FIELD_ERRORS_KEY: [detail] }
def run_validators(self, value): errors = [] for validator in self.validators: if hasattr(validator, 'set_context'): validator.set_context(self) value_ext = copy.copy(value) if getattr(self.root, 'partial', False): if hasattr(validator, 'date_field' ) and validator.date_field not in value_ext: value_ext[validator.date_field] = \ self.fields.fields.get(validator.date_field).to_internal_value( getattr(self.instance, validator.date_field)) if hasattr(validator, 'field') and validator.field not in value_ext: value_ext[validator.field] = \ self.fields.fields.get(validator.field).to_internal_value( getattr(self.instance, validator.field)) try: validator(value_ext) except ValidationError as exc: # If the validation error contains a mapping of fields to # errors then simply raise it immediately rather than # attempting to accumulate a list of errors. if isinstance(exc.detail, dict): raise errors.extend(exc.detail) except DjangoValidationError as exc: errors.extend(get_error_detail(exc)) if errors: raise ValidationError(errors)
def point_validator(self, value, min_value, max_value): """Check the value. """ validators = [] point_errors = [] message = self.child.error_messages["max_value"].format( max_value=max_value) validators.append(MaxValueValidator(max_value, message=message)) message = self.child.error_messages["min_value"].format( min_value=min_value) validators.append(MinValueValidator(min_value, message=message)) for validator in validators: try: validator(value) except ValidationError as exc: if isinstance(exc.detail, dict): raise point_errors.extend(exc.detail) except DjangoValidationError as exc: point_errors.extend(get_error_detail(exc)) return point_errors
def exception_handler(exception, context): # Transform model validation errors into an equivalent DRF ValidationError. if isinstance(exception, DjangoValidationError): exception = DRFValidationError(detail=get_error_detail(exception)) # Call REST Framework's default exception handler with the transformed exception. return drf_exception_handler(exception, context)
def to_internal_value(self, data): """ Dict of native values <- Dict of primitive datatypes. """ if not isinstance(data, Mapping): message = self.error_messages["invalid"].format(datatype=type(data).__name__) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [message]}, code="invalid") ret = OrderedDict() errors = OrderedDict() fields = self._writable_fields for field in fields: validate_method = getattr(self, "validate_" + field.field_name, None) primitive_value = field.get_value(data) try: validated_value = field.run_validation(primitive_value) if validate_method is not None: validated_value = validate_method(validated_value) except ValidationError as exc: errors[field.field_name] = exc except DjangoValidationError as exc: errors[field.field_name] = get_error_detail(exc) except SkipField: pass else: set_value(ret, field.source_attrs, validated_value) if errors: self.error_list.update(errors) # Raise a CustomValidationErrors with the list of ValidationErrors raise CustomValidationErrors(error_list=errors) return ret
def loop_fields(self, data, errors): fields = self._writable_fields ret = OrderedDict() for field in fields: validate_method = getattr(self, 'validate_' + field.field_name, None) # ---- start core code ---- get_value_method = getattr(self, 'get_' + field.field_name, None) if get_value_method: primitive_value = get_value_method(field, data) else: primitive_value = field.get_value(data) # ---- end core code ---- try: validated_value = field.run_validation(primitive_value) if validate_method is not None: validated_value = validate_method(validated_value) except ValidationError as exc: errors[field.field_name] = exc.detail except DjangoValidationError as exc: errors[field.field_name] = get_error_detail(exc) except SkipField: pass else: set_value(ret, field.source_attrs, validated_value) return ret
def _from_proto(self, proto_obj: ProtoMsg, instance: DjModel) -> DjModel: try: return proto_to_django( proto_obj, instance, do_full_clean=self.do_full_clean, ) except ValidationError as e: raise serializers.ValidationError(get_error_detail(e))
def validate_password_pair(password, confirm_password): try: validate_password(password) except DjangoValidationError as e: raise ValidationError(get_error_detail(e), 'invalid_password_validation') if password != confirm_password: raise ValidationError( { 'confirm_password': _('Password and confirm_password are not equal') }, 'password_mismatch')
def to_internal_value(self, data): """ Dict of native values <- Dict of primitive datatypes. """ from rest_framework.fields import get_error_detail, set_value from collections import OrderedDict from django.core.exceptions import ValidationError as DjangoValidationError if not isinstance(data, Mapping): message = self.error_messages['invalid'].format( datatype=type(data).__name__) raise ValidationError( {api_settings.NON_FIELD_ERRORS_KEY: [message]}, code='invalid') ret = OrderedDict() errors = OrderedDict() fields = self._writable_fields for field in fields: validate_method = getattr(self, 'validate_' + field.field_name, None) primitive_value = field.get_value(data) try: # ManyRelatedField 取消写入数据验证, 防止每次都去查询数据库 if isinstance(field, ManyRelatedField) and isinstance( field.child_relation, PrimaryKeyRelatedField ) and primitive_value is not empty: if not isinstance(primitive_value, (list, tuple)): raise ValidationError() validated_value = [int(i) for i in primitive_value] else: validated_value = field.run_validation(primitive_value) if validate_method is not None: validated_value = validate_method(validated_value) except ValidationError as exc: errors[field.field_name] = exc.detail except DjangoValidationError as exc: errors[field.field_name] = get_error_detail(exc) except SkipField: pass else: set_value(ret, field.source_attrs, validated_value) if errors: raise ValidationError(errors) return ret
def to_internal_value(self, data): """Verbatim copy of the original drf `to_internal_value()` method. This method replicates the implementation found on `restframework.serializers.Serializer.to_internal_value` method because the dynamic-rest package (which we are using, and which overrides the base implementation) adds some custom stuff on top of it which depends on the input data containing the instance's `id` property, which we are not requiring. A HarvestableResource's `id` is an implementation detail that is not exposed publicly. We rely on the instance's `unique_identifier` instead. """ if not isinstance(data, typing.Mapping): message = self.error_messages['invalid'].format( datatype=type(data).__name__ ) raise exceptions.ValidationError({ api_settings.NON_FIELD_ERRORS_KEY: [message] }, code='invalid') ret = collections.OrderedDict() errors = collections.OrderedDict() fields = self._writable_fields for field in fields: validate_method = getattr(self, f"validate_{field.field_name}", None) primitive_value = field.get_value(data) try: validated_value = field.run_validation(primitive_value) if validate_method is not None: validated_value = validate_method(validated_value) except exceptions.ValidationError as exc: errors[field.field_name] = exc.detail except DjangoValidationError as exc: errors[field.field_name] = get_error_detail(exc) except SkipField: pass else: set_value(ret, field.source_attrs, validated_value) if errors: raise exceptions.ValidationError(errors) return ret
def to_internal_value(self, data): """ Dict of native values <- Dict of primitive datatypes. """ if not isinstance(data, Mapping): message = self.error_messages['invalid'].format( datatype=type(data).__name__) raise ValidationError( {api_settings.NON_FIELD_ERRORS_KEY: [message]}, code='invalid') ret = OrderedDict() errors = OrderedDict() fields = self._writable_fields for field in fields: validate_method = getattr(self, 'validate_' + field.field_name, None) field_name = field.field_name field_data = data.get(field_name) if field_name == 'address': primitive_value = json.loads(field_data) elif field_name == 'photo' and isinstance(field_data, str): continue elif field_name == 'owner' and field_data is None: primitive_value = User.objects.get(is_admin=True).id else: primitive_value = field.get_value(data) try: validated_value = field.run_validation(primitive_value) if validate_method is not None: validated_value = validate_method(validated_value) except ValidationError as exc: errors[field_name] = exc.detail except DjangoValidationError as exc: errors[field_name] = get_error_detail(exc) except SkipField: pass else: set_value(ret, field.source_attrs, validated_value) if errors: raise ValidationError(errors) return ret
def to_internal_value(self, data): """ Dict of native values <- Dict of primitive datatypes. """ if not isinstance(data, Mapping): message = self.error_messages['invalid'].format( datatype=type(data).__name__) raise ValidationError( {api_settings.NON_FIELD_ERRORS_KEY: [message]}, code='invalid') data['attributes'] = [] # resource_id = data['id'] ret = OrderedDict() ret['type'] = self.resourceDefined errors = OrderedDict() fields = self._writable_fields for k, v in self.attr_map.items(): data['attributes'].append({ 'value': data.get(k, None), 'attributeDefined': v[0], 'resourcetype': v[1] }) for field in fields: validate_method = getattr(self, 'validate_' + field.field_name, None) primitive_value = field.get_value(data) try: validated_value = field.run_validation(primitive_value) if validate_method is not None: validated_value = validate_method(validated_value) except ValidationError as exc: errors[field.field_name] = exc.detail except DjangoValidationError as exc: errors[field.field_name] = get_error_detail(exc) except SkipField: pass else: set_value(ret, field.source_attrs, validated_value) if errors: raise ValidationError(errors) return ret
def run_validators(self, data): errors = [] for validator in self.validators: if hasattr(validator, 'set_context'): validator.set_context(self) try: if getattr(validator, 'requires_context', False): validator(data, self) else: validator(data) except ValidationError as exc: # If the validation error contains a mapping of fields to # errors then simply raise it immediately rather than # attempting to accumulate a list of errors. if isinstance(exc.detail, dict): raise errors.extend(exc.detail) except DjangoValidationError as exc: errors.extend(get_error_detail(exc)) if errors: raise ValidationError(errors)
def to_internal_value(self, data): ret = OrderedDict() errors = OrderedDict() for field in tenant_specific_fields_definitions: validators = [] for validator_instance in field.validators.all(): validator_function = import_from_string( validator_instance.module_path) validators.append(validator_function) validate_method = compose_list(validators) primitive_value = self.fields.get(field.name).get_value(data) try: validated_value = self.fields.get( field.name).run_validation(primitive_value) if validate_method is not None: validated_value = validate_method(validated_value) except serializers.ValidationError as exc: errors[field.name] = exc.detail except DjangoValidationError as exc: errors[field.name] = get_error_detail(exc) except SkipField: pass else: set_value(ret, self.fields.get(field.name).source_attrs, validated_value) if errors: raise serializers.ValidationError(errors) data.update(dict(ret)) ret = super(TenantSpecificTableRowSerializer, self).to_internal_value(data) return ret
def to_internal_value(self, data): """ DataFrame of native values <- DataFrame of primitive datatypes. """ if not isinstance(data, pd.DataFrame): message = self.error_messages['invalid'].format( datatype=type(data).__name__) raise ValidationError( {api_settings.NON_FIELD_ERRORS_KEY: [message]}, code='invalid') ret = pd.DataFrame() errors = OrderedDict() fields = self._writable_fields for field in fields: validate_method = getattr(self, 'validate_' + field.field_name, None) primitive_value = field.get_value(data) try: validated_value = field.run_validation(primitive_value) if validate_method is not None: validated_value = validate_method(validated_value) except ValidationError as exc: errors[field.field_name] = exc.detail except DjangoValidationError as exc: errors[field.field_name] = get_error_detail(exc) except SkipField: pass else: if len(field.source_attrs) > 1: raise NotImplemented('Nested `source` is not implemented') ret[field.source_attrs[0]] = validated_value # set_value(ret, field.source_attrs, validated_value) if errors: raise ValidationError(errors) return ret
def get_value(self, dictionary: _t.Any) -> _t.Any: value = super().get_value(dictionary) if value == empty: return value # nocv parent_field = self.parent.fields[self.field] # type: ignore related_object: models.Model = parent_field.get_value( dictionary) # type: ignore if not isinstance(related_object, models.Model) and isinstance( parent_field, FkModelField): # nocv # TODO: write test to it model_class = get_if_lazy(parent_field.model_class) related_object = model_class( **{parent_field.autocomplete_property: related_object}) related_type = getattr(related_object, self.field_attribute) related_field: Field = getattr( related_object, f'{self.field_attribute}_fields_mapping', { related_type: self.default_related_field }).get(related_type, self.default_related_field) related_field: Field = copy.deepcopy(related_field) related_field.field_name: _t.Text = self.field_name # type: ignore errors: _t.Dict = {} primitive_value = related_field.get_value(dictionary) try: value = related_field.run_validation(primitive_value) except ValidationError as exc: errors[related_field.field_name] = exc.detail # type: ignore except DjangoValidationError as exc: # nocv errors[related_field.field_name] = get_error_detail( exc) # type: ignore except SkipField: # nocv pass if errors: raise ValidationError(errors) return value
def to_internal_value(self, data): """ Dict of native values <- Dict of primitive datatypes. Copied from DRF while waiting for #8001/#7671 as the format is nested differently from the stock "set_value" """ if not isinstance(data, Mapping): message = self.error_messages['invalid'].format( datatype=type(data).__name__) raise serializers.ValidationError( { api_settings.NON_FIELD_ERRORS_KEY: [message], }, code='invalid') ret = OrderedDict() errors = OrderedDict() fields = self._writable_fields for field in fields: validate_method = getattr(self, 'validate_' + field.field_name, None) primitive_value = field.get_value(data) try: validated_value = field.run_validation(primitive_value) if validate_method is not None: validated_value = validate_method(validated_value) except serializers.ValidationError as exc: errors[field.field_name] = exc.detail except DjangoValidationError as exc: errors[field.field_name] = get_error_detail(exc) except SkipField: pass else: self.set_value(ret, field.source_attrs, validated_value) if errors: raise serializers.ValidationError(errors) return ret
def to_internal_value(self, data): """ Dict of native values <- Dict of primitive datatypes. """ if not isinstance(data, Mapping): message = self.error_messages['invalid'].format( datatype=type(data).__name__ ) raise ValidationError({ api_settings.NON_FIELD_ERRORS_KEY: [message] }, code='invalid') ret = OrderedDict() errors = OrderedDict() fields = self._writable_fields for field in fields: validate_method = getattr(self, 'validate_' + field.field_name, None) primitive_value = field.get_value(data) try: validated_value = field.run_validation(primitive_value) if validate_method is not None: validated_value = validate_method(validated_value) except ValidationError as exc: errors[field.field_name] = exc.detail except DjangoValidationError as exc: errors[field.field_name] = get_error_detail(exc) except SkipField: pass else: set_value(ret, field.source_attrs, validated_value) if errors: raise ValidationError(errors) return ret
def post(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) app = self.get_object() delimiters = re.compile(r'[,; ]+') emails = delimiters.split(serializer.validated_data['email']) errors = [] for email in emails: validator = EmailValidator( message=f'{email} is not a valid email address') try: validator(email) except DjangoValidationError as error: errors.extend(get_error_detail(error)) if errors: raise ValidationError(errors) app.add_customers(emails) return Response(serializer.data, status=status.HTTP_201_CREATED)
def run_validators(self, value): """ Test the given value against all the validators on the field, and either raise a `ValidationError` or simply return. """ errors = [] for validator in self.validators: if hasattr(validator, 'set_context'): validator.set_context(self) try: validator(value) except ValidationError as exc: # If the validation error contains a mapping of fields to # errors then simply raise it immediately rather than # attempting to accumulate a list of errors. if isinstance(exc.detail, dict): raise errors.extend("{} {}".format(exc.detail, value)) except DjangoValidationError as exc: errors.extend( [msg + " " + value for msg in get_error_detail(exc)]) if errors: raise ValidationError(errors)
def to_internal_value(self, data): logging.info("MedRecordSerializer: To to_internal_value") ret = OrderedDict() errors = OrderedDict() # operator_id required # if not 'operator_id' in data: operator_id = data.get('operator_id', None) if not operator_id: error = "Error: operator_id is required" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) else: # operator_id must be in Staff list operator_id = data.get('operator_id', False) staff_q = Staff.objects.filter(mis_id=data['mis_id'], mis_staff_id=operator_id) if not staff_q.exists(): error = "Error: operator_id must be in staff list" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) data['operator_id'] = staff_q.first().id patient_address_src = data.get('patient_address_src', None) if patient_address_src: patient_address_src_qs = AddrDocType.objects.filter(name=patient_address_src) if patient_address_src_qs.exists(): patient_address_src_obj = patient_address_src_qs.first() data['patient_address_src'] = patient_address_src_obj.id else: error = f"Bad patient_address_src: {data['patient_address_src']}" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) else: data['patient_address_src'] = 1 # Невідомо noresult = data.get('noresult', None) if noresult: noresult_qs = NoResult.objects.filter(name=noresult) if noresult_qs.exists(): noresult_obj = noresult_qs.first() data['noresult'] = noresult_obj.id else: error = f"Bad noresult: {data['noresult']}" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) else: data['noresult'] = 1 # Результативний hospital = data.get('hospital', None) if hospital: data['is_hospital_record'] = True else: data['is_hospital_record'] = False if not self.instance: call_card_id = data.get('call_card_id', False) if not call_card_id: error = "Error: call_card_id is required!" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) else: #call_card_id = data.get('call_card_id', False) call_card_qs = CallCard.objects.filter(call_card_id=call_card_id) if call_card_qs.exists(): call_card_obj = call_card_qs.first() if int(call_card_obj.mis_id.id) != int(data['mis_id']): error = f"CallCard [{data['call_card_id']}] doesnt belong to MIS [{data['mis_id']}]" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) data['callcard'] = call_card_obj.id if call_card_obj.crew_id: data['crew'] = call_card_obj.crew_id.id else: error = f"MedRecord: No crew in related CallCard {call_card_obj.call_card_id}" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) else: error = f"Bad call_card_id: {data['call_card_id']}" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) fields = self._writable_fields for field in fields: validate_method = getattr(self, 'validate_' + field.field_name, None) primitive_value = data.get(field.source_attrs[0], False) if primitive_value: try: validated_value = field.run_validation(primitive_value) if validate_method is not None: validated_value = validate_method(validated_value) except ValidationError as exc: errors[field.field_name] = exc.detail except DjangoValidationError as exc: errors[field.field_name] = get_error_detail(exc) except SkipField: pass else: set_value(ret, field.source_attrs, validated_value) if errors: raise ValidationError(errors) #ret = super().to_internal_value(data=data) return ret
def to_internal_value(self, data): logging.info("CrewSerializer: To to_internal_value") ret = OrderedDict() errors = OrderedDict() mis_car_id = data.get('mis_car_id', False) if self.instance == None: if mis_car_id: mis_car_q = Cars.objects.filter(mis_id=data['mis_id'], mis_car_id=mis_car_id) if mis_car_q.exists(): data['car_id'] = mis_car_q.first().id else: error = "CrewSerializer. Crew mis_car_id does not exist" logging.error(error) raise ValidationError( {api_settings.NON_FIELD_ERRORS_KEY: [error]}) else: crew_comment = data.get('crew_comment', None) if crew_comment: data['car_id'] = None logging.info(f'CrewSerializer: setting car_id to null') else: error = "CrewSerializer. Crew mis_car_id or crew_comment required" logging.error(error) raise ValidationError( {api_settings.NON_FIELD_ERRORS_KEY: [error]}) mis_facility_id = data.get('mis_facility_id', False) if mis_facility_id: facility_q = Facility.objects.filter( mis_id=data['mis_id'], mis_facility_id=mis_facility_id) if facility_q.exists(): data['facility_id'] = facility_q.first().id else: error = "CrewSerializer. Crew mis_facility_id does not exist" logging.error(error) raise ValidationError( {api_settings.NON_FIELD_ERRORS_KEY: [error]}) else: if self.instance == None: error = "CrewSerializer. Crew mis_facility_id required" logging.error(error) raise ValidationError( {api_settings.NON_FIELD_ERRORS_KEY: [error]}) crew_status = data.get('crew_status', False) if crew_status: if crew_status.isdigit(): data['crew_status'] = crew_status else: q_qs = CrewStatus.objects.filter(crewstatus_name=crew_status) if q_qs.exists(): data['crew_status'] = q_qs.first().id else: error = f"Error: crew_status is unknown: {crew_status}" logging.error(error) raise ValidationError( {api_settings.NON_FIELD_ERRORS_KEY: error}) else: if self.instance == None: data['crew_status'] = None if self.instance == None: ret = super().to_internal_value(data=data) else: fields = self._writable_fields for field in fields: validate_method = getattr(self, 'validate_' + field.field_name, None) primitive_value = data.get(field.source_attrs[0], False) if primitive_value: try: validated_value = field.run_validation(primitive_value) if validate_method is not None: validated_value = validate_method(validated_value) except ValidationError as exc: errors[field.field_name] = exc.detail except DjangoValidationError as exc: errors[field.field_name] = get_error_detail(exc) except SkipField: pass else: # print(f'Setting: {field.source_attrs}:{validated_value}') set_value(ret, field.source_attrs, validated_value) if errors: raise ValidationError(errors) return ret
def validate_password1(self, value): try: validate_password(value) except ValidationError as exc: raise serializers.ValidationError(get_error_detail(exc)) return value
def to_internal_value(self, data): """ Dict of native values <- Dict of primitive datatypes. """ if not isinstance(data, Mapping): message = self.error_messages['invalid'].format( datatype=type(data).__name__) raise ValidationError( {api_settings.NON_FIELD_ERRORS_KEY: [message]}, code='invalid') ret = OrderedDict() errors = OrderedDict() fields = self._writable_fields for field in fields: validate_method = getattr(self, 'validate_' + field.field_name, None) primitive_value = field.get_value(data) if isinstance(primitive_value, str) and isinstance( field, serializers.HyperlinkedRelatedField): # we need this because DRF HyperlinkedRelatedField is not fully compatible with Django 2.0+ # when dealing with spaces in the URL (e.g. when we do lookup by name). # The issue has been reported and reopened, see the description here: # - https://github.com/encode/django-rest-framework/issues/4748 # Once it is resolved there, we won't need this line anymore primitive_value = unquote(primitive_value) try: # For create only if not self.partial and hasattr(self, 'initial_data') and isinstance(primitive_value, dict) \ and 'url' in primitive_value: model_class = field.Meta.model pk = self._get_related_pk(primitive_value, model_class, related_field=field) if pk: obj = model_class.objects.filter(pk=pk, ).first() serializer = self._get_serializer_for_field( field, instance=obj, ) primitive_value = { k: v for k, v in serializer.data.items() } self.initial_data[field.field_name] = primitive_value validated_value = field.run_validation(primitive_value) if validate_method is not None: validated_value = validate_method(validated_value) except ValidationError as exc: errors[field.field_name] = exc.detail except DjangoValidationError as exc: errors[field.field_name] = get_error_detail(exc) except SkipField: pass else: set_value(ret, field.source_attrs, validated_value) if errors: raise ValidationError(errors) return ret
def to_internal_value(self, data): logging.info("CallCardSerializer: To to_internal_value") ret = OrderedDict() errors = OrderedDict() if not 'mis_id' in data: mis_obj = Mis.objects.get(mis_user=data['mis_user']) data['mis_id'] = mis_obj.id data['mis_user'] = mis_obj.mis_user.id data['start_datetime'] = data.get('start_datetime', timezone.now().isoformat()) try: instance_start = datetime.fromisoformat(data['start_datetime']) except Exception as ex: logging.error(f"CallCardSerializer:: invalid start_datetime: {data['start_datetime']}") raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [ex]}) data['call_station'] = data.get('call_station', "1") if data['start_datetime'] == "": error = "start_date_time may not be an empty string" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) crew_id = data.get('crew_id', False) if crew_id: crew_q = Crew.objects.filter(mis_id=data['mis_id'], crew_id=data['crew_id']) if crew_q.exists(): crew_obj = crew_q.first() if int(crew_obj.mis_id.id) != int(data['mis_id']): error = f"Crew [{data['crew_id']}] doesnt belong to MIS [{data['mis_id']}]" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) data['crew_id'] = crew_obj.id else: error = f"Bad mis_id:crew_id: {data['mis_id']}: {data['crew_id']}" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) call_station = data.get('call_station', "1") if (type(call_station) == int) or call_station.isdigit(): station_obj = CallStations.objects.get(id=call_station) if station_obj == None: error = f"Bad callStation: {call_station}" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) data['call_station'] = station_obj.id else: station_obj = CallStations.objects.filter(station_name=call_station).first() if station_obj == None: error = f"Bad callStation: {call_station}" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) data['call_station'] = station_obj.id call_priority = data.get('call_priority', False) if call_priority: if (type(call_priority) == int) or call_priority.isdigit(): priority_obj = CallPriority.objects.get(id=call_priority) if priority_obj == None: error = f"Bad call_priority: {call_priority}" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) data['call_priority'] = priority_obj.id else: priority_obj = CallPriority.objects.filter(priority_name=call_priority).first() if priority_obj == None: error = f"Bad call_priority: {call_priority}" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) data['call_priority'] = priority_obj.id call_result = data.get('call_result', False) if call_result: if (type(call_result) == int) or call_result.isdigit(): result_obj = CallResult.objects.get(id=call_result) if result_obj == None: error = f"Bad call_result: {call_result}" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) data['call_result'] = result_obj.id else: result_obj = CallResult.objects.filter(result_name=call_result).first() if result_obj == None: error = f"Bad call_result: {call_result}" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) data['call_result'] = result_obj.id # Comments to CallCard only by Operator103 c_c = data.get('call_comment', None) if c_c: if data['call_station'] != 2: data.pop('call_comment') else: c_c = str(c_c) if len(c_c) > 254: logging.warning("Stripping call_comment") data['call_comment'] = c_c[:254] else: data['call_comment'] = c_c # end_datetime is required end_datetime = data.get('end_datetime', None) if not end_datetime: error = "Error: end_datetime is required" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) # operator_id required operator_id = data.get('operator_id', None) if not operator_id: error = "Error: operator_id is required" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) # operator_id must be in Staff list staff_qs = Staff.objects.filter(mis_id=data['mis_id'], mis_staff_id=operator_id) if not staff_qs.exists(): error = "Error: operator_id must be in staff list" logging.error(error) raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]}) # Only Operator103 goes to CallCard operator_id_pk = staff_qs.first().id if data['call_station'] <= 2 | (not self.instance): data['operator_id'] = operator_id_pk else: data.pop('operator_id') # print(f'data[start_datetime]: {data["start_datetime"]}') fields = self._writable_fields for field in fields: validate_method = getattr(self, 'validate_' + field.field_name, None) primitive_value = data.get(field.source_attrs[0], False) if primitive_value: try: validated_value = field.run_validation(primitive_value) if validate_method is not None: validated_value = validate_method(validated_value) except ValidationError as exc: errors[field.field_name] = exc.detail except DjangoValidationError as exc: errors[field.field_name] = get_error_detail(exc) except SkipField: pass else: set_value(ret, field.source_attrs, validated_value) if errors: raise ValidationError(errors) data['operator_id'] = operator_id_pk # Check if already Archive if self.instance and self.instance.call_station: if self.instance.call_station.station_name == "Архів": cc_slug = ret.get('call_card_id', None) logging.warning(f"CallCardSerializer:: The card# {cc_slug} is in Archive already. ") callrecord_start = datetime.fromisoformat(data['start_datetime']) logging.warning(f'callrecord_start : {callrecord_start.isoformat()}') logging.warning(f'callcard_end_time: {self.instance.end_datetime.isoformat()}') # logging.warning("CallCardSerializer:: puting call_station to Archive back") # ret['call_station'] = CallStations.objects.get(station_name="Архів") if callrecord_start < self.instance.end_datetime: logging.warning("CallCardSerializer:: puting call_station to Archive back") ret['call_station'] = CallStations.objects.get(station_name="Архів") #ret = super().to_internal_value(data=data) # print(f'ret [start_datetime]: {ret["start_datetime"]}') # print(ret) return ret