class CursorUUIDRequestSerializer(PerPageSerializerBase): after = UUIDField(required=False, allow_null=True, help_text=_('After UUID')) before = UUIDField(required=False, allow_null=True, help_text=_('Before UUID'))
def parse_uuid_list(value): """Parses a comma-separated list of UUIDs from a string.""" if not value or value.lower().strip() == 'null': return [] field = UUIDField() return [field.to_internal_value(item) for item in value.split(',')]
class IngredientCompositionCreateUpdateSerializer(BaseCreateUpdateSerializer): ingredient_uuid = UUIDField(source="ingredient.uuid") measurement_uuid = UUIDField(source="measurement.uuid") class Meta: model = IngredientComposition fields = ( "uuid", "ingredient_uuid", "measurement_uuid", "quantity", "user", "notes", ) def validate_ingredient_uuid(self, value): user = self.context["request"].user validate_model_uuid(Ingredient, uuid=value, user=user) return value def validate_measurement_uuid(self, value): validate_model_uuid(Measurement, uuid=value) return value def validate(self, validated_data): user = self.context["request"].user is_creating_instance = not self.instance if validated_data.get("ingredient"): ingredient_uuid = validated_data.pop("ingredient")["uuid"] ingredient = Ingredient.objects.get(uuid=ingredient_uuid, user=user) validated_data["ingredient"] = ingredient if validated_data.get("measurement"): measurement_uuid = validated_data.pop("measurement")["uuid"] measurement = Measurement.objects.get(uuid=measurement_uuid) validated_data["measurement"] = measurement # check for uniqueconstraints issues with creation # for updates, probably be a little bit easier # and skip for now if is_creating_instance: if self.Meta.model.objects.filter( user=user, ingredient=ingredient, measurement=measurement, quantity=validated_data["quantity"], ).exists(): raise ValidationError( f"Fields user, ingredient, measurement, and quantity are not unique!" ) return validated_data
class CursorUUIDUncountedResponseSerializer(Serializer): after = UUIDField(required=False, allow_null=True, help_text=_('After UUID')) before = UUIDField(required=False, allow_null=True, help_text=_('Before UUID')) per_page = IntegerField( required=True, max_value=DEFAULT_MAX_PAGE_SIZE, help_text=_('Page size'), ) has_next = BooleanField(help_text=_('Has result next page')) url = CharField(help_text=_('Current page URL')) after_url = CharField(help_text=_('URL of page after cursor position'), allow_null=True) before_url = CharField(help_text=_('URL of page before cursor position'), allow_null=True)
class ApplicationSerializer(serializers.ModelSerializer): application_uuid = UUIDField(source="external_uuid") application_type = EnumField(ApplicationType, source="type", write_only=True) additional_applicant = ApplicantSerializer(write_only=True, allow_null=True) project_id = UUIDField(write_only=True) ssn_suffix = CharField(write_only=True, min_length=5, max_length=5) apartments = ApplicationApartmentSerializer(write_only=True, many=True) class Meta: model = Application fields = [ "application_uuid", "application_type", "ssn_suffix", "has_children", "additional_applicant", "right_of_residence", "project_id", "apartments", ] extra_kwargs = { # We only support creating applications for now, # and only the application UUID will be returned # in the response. "has_children": { "write_only": True }, "right_of_residence": { "write_only": True }, "project_id": { "write_only": True }, } def validate_ssn_suffix(self, value): date_of_birth = self.context["request"].user.profile.date_of_birth validator = SSNSuffixValidator(date_of_birth) try: validator(value) except ValidationError as e: _logger.warning( "Invalid SSN suffix for the primary applicant was received: %s", e) return value def create(self, validated_data): validated_data["profile"] = self.context["request"].user.profile return create_application(validated_data)
class SupplementLogCreateUpdateSerializer(BaseCreateUpdateSerializer): supplement_uuid = UUIDField(source="supplement.uuid") user = HiddenField(default=CurrentUserDefault()) uuid = UUIDField(required=False, read_only=True) notes = CharField( default="", trim_whitespace=True, required=False, allow_blank=True, ) quantity = DecimalField(decimal_places=4, max_digits=10, default=1) source = ChoiceField(INPUT_SOURCES_TUPLES, default=WEB_INPUT_SOURCE) class Meta: model = SupplementLog fields = ( "user", "uuid", "notes", "supplement_uuid", "source", "quantity", "time", "duration_minutes", ) def validate_supplement_uuid(self, value): user = self.context["request"].user validate_model_uuid(Supplement, uuid=value, user=user) return value def validate(self, validated_data): user = self.context["request"].user is_creating_instance = not self.instance if validated_data.get("supplement"): supplement_uuid = validated_data["supplement"]["uuid"] supplement = Supplement.objects.get(uuid=supplement_uuid, user=user) validated_data["supplement"] = supplement if is_creating_instance: if self.Meta.model.objects.filter( user=user, supplement=supplement, time=validated_data["time"], ).exists(): raise ValidationError( f"Fields user, supplement, and time are not unique!") return validated_data
class RoundSerializer(serializers.ModelSerializer): appearances = AppearanceSerializer(read_only=True, many=True) panelists = PanelistSerializer(read_only=True, many=True) outcomes = OutcomeSerializer(read_only=True, many=True) session = serializers.PrimaryKeyRelatedField( read_only=True, pk_field=UUIDField(format='hex_verbose'), allow_null=True, ) class Meta: model = Round fields = ( 'id', 'get_kind_display', 'num', 'date', 'spots', 'footnotes', 'appearances', 'panelists', 'outcomes', 'session', )
class ExperimentCreateSerializer(serializers.ModelSerializer): class Meta: model = Experiment fields = ['name', 'project'] project = serializers.PrimaryKeyRelatedField( queryset=Project.objects.all(), pk_field=UUIDField())
class FullAppointmentSerializer(ModelSerializer): invitee = UUIDField(source='invitee.uuid', read_only=True) def create(self, validated_data): user = self.context["request"].user validated_data["owner"] = user return super(FullAppointmentSerializer, self).create(validated_data) class Meta: model = models.Appointment fields = [ 'id', 'owner', 'timeslot', 'start_time', 'duration', 'subject', 'topic', 'invitee', 'status' ] extra_kwargs = { 'timeslot': { 'allow_null': True }, 'subject': { 'allow_null': False }, } read_only_fields = ['owner', 'invitee', 'status'] validators = [ validators.AppointmentValidator( queryset=Appointment.objects.all()), UniqueTogetherValidator( queryset=Appointment.objects.all(), fields=['timeslot', 'start_time'], message=_("Only one appointment can start at this time!")) ]
class UserDeleteSerializer(Serializer): # most of this is actually redundant, i don't need to have a validation step, but i do this # out of paranoia reasons that someone may delete their account by mistake password = CharField() user = HiddenField(default=CurrentUserDefault()) uuid = UUIDField() def validate(self, data): user = data["user"] validated_password = check_password(data["password"], user.password) if not validated_password: raise ValidationError("Invalid Password Entered") validated_uuid = str(user.uuid) == str(data["uuid"]) if not validated_uuid: raise ValidationError("Invalid UUID", str(user.uuid)) validate_user = user.username != "*****@*****.**" if not validate_user: raise ValidationError( f"This is a protected user and cannot be deleted. {user.username}" ) return data
class FoodLogCreateUpdateSerializer(BaseCreateUpdateSerializer, ModelValidatorsMixin): food_uuid = UUIDField(source="food.uuid") class Meta: model = FoodLog fields = ( "food_uuid", "quantity", "time", "notes", "user", ) def validate(self, validated_data): user = self.context["request"].user is_creating_instance = not self.instance if validated_data.get("food"): food_uuid = validated_data.pop("food")["uuid"] food = Food.objects.get(uuid=food_uuid, user=user) validated_data["food"] = food if is_creating_instance: if self.Meta.model.objects.filter( user=user, food=food, time=validated_data["time"], ).exists(): raise ValidationError( f"Fields user, food, and time are not unique!") return validated_data
class ActivityLogCreateUpdateSerializer(BaseCreateUpdateSerializer, ModelValidatorsMixin): activity_uuid = UUIDField(source="activity.uuid") class Meta: model = ActivityLog fields = ( "activity_uuid", "source", "duration_minutes", "time", "notes", "user", ) def validate(self, validated_data): user = self.context["request"].user is_creating_instance = not self.instance if validated_data.get("activity"): activity_uuid = validated_data.pop("activity")["uuid"] activity = Activity.objects.get(uuid=activity_uuid, user=user) validated_data["activity"] = activity if is_creating_instance: if self.Meta.model.objects.filter( user=user, activity=activity, time=validated_data["time"], ).exists(): raise ValidationError( f"Fields user, ingredient, measurement, and quantity are not unique!" ) return validated_data
class InternshipStudentAffectationSerializer( serializers.HyperlinkedModelSerializer): url = serializers.HyperlinkedIdentityField( view_name='internship_api_v1:student-affectation-detail', lookup_field='uuid') student = InternshipStudentSerializer(read_only=True) organization = UUIDField(source='organization.uuid', read_only=True) speciality = UUIDField(source='speciality.uuid', read_only=True) internship = serializers.CharField(read_only=True, source='internship.name') period = PeriodSerializer(read_only=True) score = InternshipScoreListSerializer(read_only=True) class Meta: model = InternshipStudentAffectationStat fields = ('url', 'uuid', 'student', 'organization', 'speciality', 'period', 'internship', 'score')
class ExperimentSerializer(serializers.ModelSerializer): class Meta: model = Experiment fields = ['id', 'name', 'lock_owner', 'scans', 'project', 'note'] ref_name = 'project_experiment' scans = ScanSerializer(many=True) lock_owner = LockOwnerSerializer() project = serializers.PrimaryKeyRelatedField(read_only=True, pk_field=UUIDField())
class WriteUpFlaggedPromptModifySerializer(serializers.ModelSerializer): """ FLAGGING """ prompt_uuid = UUIDField(required=True) class Meta: model = WriteUpFlaggedPrompt fields = ("prompt_uuid", )
class AvailableSlotSerializer(Serializer): def update(self, instance, validated_data): pass def create(self, validated_data): pass # parent = TimeSlotSerializer(fields=['owner']) owner = UUIDField(source='parent.owner_id') start_time = DateTimeField(read_only=True) duration = DurationField(read_only=True)
class StagedFileSerializer(ModelSerializer): filename = CharField(source="client_filename") uuid = UUIDField(source="file_id", read_only=True) extra_attrs = SerializerMethodField(source="get_extra_attrs") class Meta: model = StagedFile fields = ( "client_id", "end_byte", "extra_attrs", "file", "filename", "start_byte", "timeout", "total_size", "user_pk_str", "uuid", ) extra_kwargs = { "client_id": { "write_only": True }, "end_byte": { "write_only": True }, "file": { "write_only": True }, "start_byte": { "write_only": True }, "timeout": { "write_only": True }, "user_pk_str": { "write_only": True }, "total_size": { "write_only": True }, } def get_extra_attrs(self, *_): return {} def validate(self, attrs): instance = StagedFile(**attrs) instance.clean() # This is set in the clean method attrs.update({"file_id": instance.file_id}) return attrs
class TinyPicklistSerializer(ModelSerializer): id = UUIDField(read_only=True) name = CharField(read_only=True) text = CharField(read_only=True) class Meta: model = PicklistItem fields = ( "id", "name", "text", "updated_at", )
def __init__(self, model, extra_fields=('name', ), **kwargs): """Initialises the related field. :param model: Model of the related field. :param extra_fields: List of extra fields to include in the representation. Can contain field names as strings or as tuples of (field name, DRF field). E.g. ['field1', ('field2', CharField())] :param kwargs: Keyword arguments to pass to RelatedField.__init__() """ super().__init__(**kwargs) model_class = (apps.get_model(model) if isinstance(model, str) else model) self.pk_field = UUIDField() self._fields = [ field if isinstance(field, tuple) else (field, ReadOnlyField()) for field in extra_fields ] self._model = model_class
class AggregrateViewParamsSerializer(Serializer): start_date = DateField() end_date = DateField() supplement_uuids = ListField( child=UUIDField(validators=[generic_model_uuid_validator(Supplement)]), required=False, ) activity_uuids = ListField( child=UUIDField(validators=[generic_model_uuid_validator(Activity)]), required=False, ) food_uuids = ListField( child=UUIDField(validators=[generic_model_uuid_validator(Food)]), required=False ) class Meta: fields = ( "start_date", "end_date", "supplement_uuids", "activity_uuids", "food_uuids", )
class TodoSerializer(BaseSerializer): uuid = UUIDField(read_only=True) class Meta: model = Todo exclude = ('authority', 'url') def get_fields(self): fields = super().get_fields() authority = get_the_authority(self.context['request'].user) fields['assigned_to'] = hyperlinkedRelatedFieldByAuthority(Staff, 'staff-detail', authority, False) fields['status'] = hyperlinkedRelatedFieldByAuthority(Status, 'status-detail', authority, False) return fields
class AppearanceSerializer(serializers.ModelSerializer): songs = SongSerializer(read_only=True, many=True) group = serializers.PrimaryKeyRelatedField( read_only=True, pk_field=UUIDField(format='hex_verbose'), allow_null=True, ) entry = serializers.PrimaryKeyRelatedField( read_only=True, pk_field=UUIDField(format='hex_verbose'), allow_null=True, ) class Meta: model = Appearance fields = ( 'id', 'num', 'draw', 'is_private', 'is_single', 'participants', 'representing', 'onstage', 'actual_start', 'actual_finish', 'legacy_group', 'pos', 'stats', 'base', 'variance_report', 'group', 'entry', 'songs', )
class ProfileSerializer(ModelSerializer): id = UUIDField(source="pk") email = EmailField(source="user.email") first_name = CharField(source="user.first_name", max_length=30) last_name = CharField(source="user.last_name", max_length=150) class Meta: model = Profile fields = [ "id", "first_name", "last_name", "email", "phone_number", "street_address", "date_of_birth", "city", "postal_code", "contact_language", ] @transaction.atomic def create(self, validated_data): _logger.info("Creating a new profile") user = get_user_model().objects.create(**validated_data.pop("user")) profile = Profile.objects.create(user=user, **validated_data) _logger.info(f"Profile {profile.pk} created") return profile @transaction.atomic def update(self, instance, validated_data): _logger.info(f"Updating profile {instance.pk}") user = instance.user user_data = validated_data.pop("user", {}) for attr, value in user_data.items(): setattr(user, attr, value) user.save() for attr, value in validated_data.items(): setattr(instance, attr, value) instance.save() _logger.info(f"Profile {instance.pk} updated") return instance class CreateResponseSerializer(Serializer): profile_id = CharField() password = CharField()
class APNSDeviceSerializer(ModelSerializer): device_id = UUIDField( help_text= "UDID / UIDevice.identifierForVendor() (e.g. 5ce0e9a5-5ffa-654b-cee0-1238041fb31a)", style={'input_type': 'text'}, required=False) class Meta(DeviceSerializerMixin.Meta): model = APNSDevice def validate_registration_id(self, value): # iOS device tokens are 256-bit hexadecimal (64 characters) if hex_re.match(value) is None or len(value) != 64: raise ValidationError("Registration ID (device token) is invalid") return value
class PanelistSerializer(serializers.ModelSerializer): scores = ScoreSerializer(read_only=True, many=True) person = serializers.PrimaryKeyRelatedField( read_only=True, pk_field=UUIDField(format='hex_verbose'), allow_null=True, ) class Meta: model = Panelist fields = ( 'id', 'num', 'get_kind_display', 'get_category_display', 'psa_report', 'legacy_person', 'representing', 'person_id', 'scores', )
class BaseCreateUpdateSerializer(ModelSerializer): uuid = UUIDField(required=False, read_only=True) user = HiddenField(default=CurrentUserDefault()) # if you don't have this when notes is sent with "null/none", database integrity has an issue # since serializers will try to input that into the db notes = CharField( default="", trim_whitespace=True, required=False, allow_blank=True, ) def create(self, validated_data): create_model = self.Meta.model obj = create_model.objects.create(**validated_data) return obj def update(self, instance, validated_data): for key, value in validated_data.items(): setattr(instance, key, value) instance.save() return instance
class ProjectSerializer(GroupHyperlinksSerializer, BaseSerializer): uuid = UUIDField(read_only=True) class Meta: model = Project exclude = ('status_group', 'authority') expandable_fields = { 'company': CompanySerializer, } def get_fields(self): fields = super().get_fields() authority = get_the_authority(self.context['request'].user) fields['company'] = hyperlinkedRelatedFieldByAuthority(Company, 'company-detail', authority, False) return fields def to_representation(self, instance): representation = super().to_representation(instance) if self.context['request'].method == 'POST': representation['company'] = {'name': instance.company.name} return representation
def parse_uuid(value): """Parses a UUID from a string.""" return _parse_value(value, UUIDField())
class ConceptDetailSerializer(ModelSerializer): uuid = CharField(source='id', read_only=True) version = CharField(read_only=True) type = CharField(source='versioned_resource_type', read_only=True) id = CharField(source='mnemonic', required=True) source = CharField(source='parent_resource', read_only=True) parent_id = UUIDField() owner = CharField(source='owner_name', read_only=True) created_on = DateTimeField(source='created_at', read_only=True) updated_on = DateTimeField(source='updated_at', read_only=True) names = LocalizedNameSerializer(many=True) descriptions = LocalizedDescriptionSerializer(many=True, allow_null=True) external_id = CharField(required=False, allow_blank=True) concept_class = CharField(required=True) datatype = CharField(required=True) display_name = CharField(read_only=True) display_locale = CharField(read_only=True) retired = BooleanField(required=False) owner_type = CharField(read_only=True) owner_url = URLField(read_only=True) extras = JSONField(required=False, allow_null=True) update_comment = CharField(required=False, source='comment') mappings = SerializerMethodField() url = CharField(required=False, source='versioned_object_url') updated_by = DateTimeField(source='updated_by.username', read_only=True) created_by = DateTimeField(source='created_by.username', read_only=True) def __init__(self, *args, **kwargs): self.query_params = kwargs.get('context').get('request').query_params.dict() self.include_indirect_mappings = self.query_params.get(INCLUDE_INVERSE_MAPPINGS_PARAM) == 'true' self.include_direct_mappings = self.query_params.get(INCLUDE_MAPPINGS_PARAM) == 'true' super().__init__(*args, **kwargs) class Meta: model = Concept fields = ( 'uuid', 'id', 'external_id', 'concept_class', 'datatype', 'url', 'retired', 'source', 'owner', 'owner_type', 'owner_url', 'display_name', 'display_locale', 'names', 'descriptions', 'created_on', 'updated_on', 'versions_url', 'version', 'extras', 'parent_id', 'name', 'type', 'update_comment', 'version_url', 'mappings', 'updated_by', 'created_by' ) def get_mappings(self, obj): if self.include_indirect_mappings: return MappingDetailSerializer(obj.get_bidirectional_mappings(), many=True).data if self.include_direct_mappings: return MappingDetailSerializer(obj.get_unidirectional_mappings(), many=True).data return [] def create(self, validated_data): concept = Concept.persist_new(data=validated_data, user=self.context.get('request').user) self._errors.update(concept.errors) return concept def update(self, instance, validated_data): instance.concept_class = validated_data.get('concept_class', instance.concept_class) instance.datatype = validated_data.get('datatype', instance.datatype) instance.extras = validated_data.get('extras', instance.extras) instance.external_id = validated_data.get('external_id', instance.external_id) instance.comment = validated_data.get('update_comment') or validated_data.get('comment') instance.retired = validated_data.get('retired', instance.retired) new_names = [ LocalizedText( **{k: v for k, v in name.items() if k not in ['name_type']} ) for name in validated_data.get('names', []) ] new_descriptions = [ LocalizedText( **{k: v for k, v in desc.items() if k not in ['description_type']} ) for desc in validated_data.get('descriptions', []) ] instance.cloned_names = compact(new_names) instance.cloned_descriptions = compact(new_descriptions) errors = Concept.persist_clone(instance, self.context.get('request').user) if errors: self._errors.update(errors) return instance
class ListFilterSerialiser(Serializer): filter_uuid_field = UUIDField(required=False) filter_field = CharField(allow_null=True, help_text='Help text')