class GroupListSerializer(serializers.HyperlinkedModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='quser:group-detail') class Meta: model = Group fields = utils.generate_fields(Group, remove=['permissions', ])
class Meta: model = Customer url = serializers.HyperlinkedIdentityField(view_name='customer', lookup_field='id') fields = ('id', 'url', 'address', 'phone_number', 'user')
class Meta: model = Cardreading url = serializers.HyperlinkedIdentityField(view_name='card', lookup_field='id') fields = ('id', 'card', 'position_id', 'inverted')
class Meta: model = ClimbingType url = serializers.HyperlinkedIdentityField(view_name='climbingtype', lookup_field='id') fields = ('id', 'url', 'type_name') depth = 2
class CustomerListSerializer(serializers.ModelSerializer): cash_equivalency = SerializerMethodField() edit_url = serializers.HyperlinkedIdentityField( view_name='dashboard:customer-edit') sales_url = serializers.HyperlinkedIdentityField( view_name='dashboard:customer-sales-detail') detail_url = serializers.HyperlinkedIdentityField( view_name='dashboard:customer-detail') delete_url = serializers.HyperlinkedIdentityField( view_name='dashboard:customer-delete') image = serializers.SerializerMethodField() bill_full = serializers.SerializerMethodField() bill_pending = serializers.SerializerMethodField() bill_paid = serializers.SerializerMethodField() class Meta: model = Customer fields = ( 'id', 'name', 'email', 'mobile', 'image', 'sales_url', 'delete_url', 'edit_url', 'detail_url', 'loyalty_points', 'redeemed_loyalty_points', 'cash_equivalency', 'bill_full', 'bill_paid', 'bill_pending', ) def get_image(self, obj): image = '' if obj.image: image = obj.image.url else: image = image64() return image def get_bill_full(self, obj): return Bill.objects.customer_bills(obj, status='all') def get_bill_paid(self, obj): return Bill.objects.customer_bills(obj, 'fully-paid') def get_bill_pending(self, obj): return Bill.objects.customer_bills(obj, 'pending') def get_cash_equivalency(self, obj): points_eq = PaymentOption.objects.filter(name='Loyalty Points') if not points_eq.exists(): points_eq = 0 else: points_eq = points_eq.get().loyalty_point_equiv if points_eq != 0: return obj.loyalty_points / Decimal(points_eq) return 0
class Meta: model = Attraction url = serializers.HyperlinkedIdentityField(view_name='attraction', lookup_field='id') fields = ('id', 'url', 'name', 'area')
class PlaceSerializer(serializers.ModelSerializer): uploaded_by = serializers.PrimaryKeyRelatedField(read_only=True) coordinates = CoordinatesField() address = serializers.SerializerMethodField() events = EventSerializer(many=True, read_only=True) images = serializers.SerializerMethodField() police_rating = serializers.ChoiceField(choices=Place.POLICE_RATING) average_price = serializers.SerializerMethodField() pinyin_address = serializers.SerializerMethodField() reviews = ReviewSerializer(many=True, read_only=True, source="show_visible_reviews") logo = serializers.SerializerMethodField('get_logo_url') phone_number = serializers.SerializerMethodField() rating = serializers.SerializerMethodField() rating_status = serializers.SerializerMethodField() detailsUrl = serializers.HyperlinkedIdentityField( view_name="places-detail", lookup_field='pk') class Meta: model = Place fields = ( 'id', 'uploaded_by', 'title', 'logo', 'category', 'address', 'pinyin_address', 'phone_number', 'description', 'average_price', 'police_rating', 'opening_hours', 'closing_hours', 'coordinates', 'events', 'images', 'rating', 'rating_status', 'reviews', 'detailsUrl', ) def create(self, validated_data): validated_data.update({ 'uploaded_by': self.context['request'].user, }) place = Place.objects.create(**validated_data) return Place.objects.filter( id=place.id).calculate_auto_fill_fields()[0] def get_coordinates(self, place): return { 'longitude': place.longitude, 'latitude': place.latitude, } def to_representation(self, place): ret = super().to_representation(place) ret['police_rating'] = represent_choices(ret, 'police_rating', Place.POLICE_RATING) ret['category'] = represent_choices(ret, 'category', Place.CATEGORIES) return ret def get_average_price(self, place): return place.average_price def get_pinyin_address(self, place): return place.pinyin_address def get_images(self, place): return [image.image.url for image in place.images.all()] def get_logo_url(self, place): return place.logo_url() def get_phone_number(self, place): return place.standardize_phone_number() def get_rating(self, place): return place.rating def get_rating_status(self, place): return get_rating_status(place.rating) def get_address(self, place): return place.address.replace('河南省', '').replace('郑州市', '')
class DeviceSerializer(TaggedObjectSerializer, StatusModelSerializerMixin, CustomFieldModelSerializer): url = serializers.HyperlinkedIdentityField( view_name="dcim-api:device-detail") device_type = NestedDeviceTypeSerializer() device_role = NestedDeviceRoleSerializer() tenant = NestedTenantSerializer(required=False, allow_null=True) platform = NestedPlatformSerializer(required=False, allow_null=True) site = NestedSiteSerializer() rack = NestedRackSerializer(required=False, allow_null=True) face = ChoiceField(choices=DeviceFaceChoices, allow_blank=True, required=False) primary_ip = NestedIPAddressSerializer(read_only=True) primary_ip4 = NestedIPAddressSerializer(required=False, allow_null=True) primary_ip6 = NestedIPAddressSerializer(required=False, allow_null=True) parent_device = serializers.SerializerMethodField() cluster = NestedClusterSerializer(required=False, allow_null=True) virtual_chassis = NestedVirtualChassisSerializer(required=False, allow_null=True) class Meta: model = Device fields = [ "id", "url", "name", "device_type", "device_role", "tenant", "platform", "serial", "asset_tag", "site", "rack", "position", "face", "parent_device", "status", "primary_ip", "primary_ip4", "primary_ip6", "cluster", "virtual_chassis", "vc_position", "vc_priority", "comments", "local_context_data", "tags", "custom_fields", "created", "last_updated", ] validators = [] def validate(self, data): # Validate uniqueness of (rack, position, face) since we omitted the automatically-created validator from Meta. if data.get("rack") and data.get("position") and data.get("face"): validator = UniqueTogetherValidator(queryset=Device.objects.all(), fields=("rack", "position", "face")) validator(data, self) # Enforce model validation super().validate(data) return data @swagger_serializer_method(serializer_or_field=NestedDeviceSerializer) def get_parent_device(self, obj): try: device_bay = obj.parent_bay except DeviceBay.DoesNotExist: return None context = {"request": self.context["request"]} data = NestedDeviceSerializer(instance=device_bay.device, context=context).data data["device_bay"] = NestedDeviceBaySerializer(instance=device_bay, context=context).data return data
class InterfaceSerializer( TaggedObjectSerializer, CableTerminationSerializer, ConnectedEndpointSerializer, CustomFieldModelSerializer, ): url = serializers.HyperlinkedIdentityField( view_name="dcim-api:interface-detail") device = NestedDeviceSerializer() type = ChoiceField(choices=InterfaceTypeChoices) lag = NestedInterfaceSerializer(required=False, allow_null=True) mode = ChoiceField(choices=InterfaceModeChoices, allow_blank=True, required=False) untagged_vlan = NestedVLANSerializer(required=False, allow_null=True) tagged_vlans = SerializedPKRelatedField( queryset=VLAN.objects.all(), serializer=NestedVLANSerializer, required=False, many=True, ) cable = NestedCableSerializer(read_only=True) count_ipaddresses = serializers.IntegerField(read_only=True) class Meta: model = Interface fields = [ "id", "url", "device", "name", "label", "type", "enabled", "lag", "mtu", "mac_address", "mgmt_only", "description", "mode", "untagged_vlan", "tagged_vlans", "cable", "cable_peer", "cable_peer_type", "connected_endpoint", "connected_endpoint_type", "connected_endpoint_reachable", "tags", "count_ipaddresses", "custom_fields", ] def validate(self, data): # Validate many-to-many VLAN assignments device = self.instance.device if self.instance else data.get("device") for vlan in data.get("tagged_vlans", []): if vlan.site not in [device.site, None]: raise serializers.ValidationError({ "tagged_vlans": f"VLAN {vlan} must belong to the same site as the interface's parent device, or " f"it must be global." }) return super().validate(data)
class InterfaceSerializer(PrimaryModelSerializer, CableTerminationSerializer, ConnectedEndpointSerializer): url = serializers.HyperlinkedIdentityField( view_name='dcim-api:interface-detail') device = NestedDeviceSerializer() type = ChoiceField(choices=InterfaceTypeChoices) parent = NestedInterfaceSerializer(required=False, allow_null=True) lag = NestedInterfaceSerializer(required=False, allow_null=True) mode = ChoiceField(choices=InterfaceModeChoices, allow_blank=True, required=False) untagged_vlan = NestedVLANSerializer(required=False, allow_null=True) tagged_vlans = SerializedPKRelatedField(queryset=VLAN.objects.all(), serializer=NestedVLANSerializer, required=False, many=True) cable = NestedCableSerializer(read_only=True) count_ipaddresses = serializers.IntegerField(read_only=True) class Meta: model = Interface fields = [ 'id', 'url', 'display', 'device', 'name', 'label', 'type', 'enabled', 'parent', 'lag', 'mtu', 'mac_address', 'mgmt_only', 'description', 'mode', 'untagged_vlan', 'tagged_vlans', 'mark_connected', 'cable', 'cable_peer', 'cable_peer_type', 'connected_endpoint', 'connected_endpoint_type', 'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'last_updated', 'count_ipaddresses', '_occupied', ] def validate(self, data): # Validate many-to-many VLAN assignments device = self.instance.device if self.instance else data.get('device') for vlan in data.get('tagged_vlans', []): if vlan.site not in [device.site, None]: raise serializers.ValidationError({ 'tagged_vlans': f"VLAN {vlan} must belong to the same site as the interface's parent device, or " f"it must be global." }) return super().validate(data)
class RackSerializer(TaggedObjectSerializer, StatusModelSerializerMixin, CustomFieldModelSerializer): url = serializers.HyperlinkedIdentityField( view_name="dcim-api:rack-detail") site = NestedSiteSerializer() group = NestedRackGroupSerializer(required=False, allow_null=True, default=None) tenant = NestedTenantSerializer(required=False, allow_null=True) role = NestedRackRoleSerializer(required=False, allow_null=True) type = ChoiceField(choices=RackTypeChoices, allow_blank=True, required=False) width = ChoiceField(choices=RackWidthChoices, required=False) outer_unit = ChoiceField(choices=RackDimensionUnitChoices, allow_blank=True, required=False) device_count = serializers.IntegerField(read_only=True) powerfeed_count = serializers.IntegerField(read_only=True) class Meta: model = Rack fields = [ "id", "url", "name", "facility_id", "site", "group", "tenant", "status", "role", "serial", "asset_tag", "type", "width", "u_height", "desc_units", "outer_width", "outer_depth", "outer_unit", "comments", "tags", "custom_fields", "created", "last_updated", "device_count", "powerfeed_count", ] # Omit the UniqueTogetherValidator that would be automatically added to validate (group, facility_id). This # prevents facility_id from being interpreted as a required field. validators = [ UniqueTogetherValidator(queryset=Rack.objects.all(), fields=("group", "name")) ] def validate(self, data): # Validate uniqueness of (group, facility_id) since we omitted the automatically-created validator from Meta. if data.get("facility_id", None): validator = UniqueTogetherValidator(queryset=Rack.objects.all(), fields=("group", "facility_id")) validator(data, self) # Enforce model validation super().validate(data) return data
class DeviceSerializer(PrimaryModelSerializer): url = serializers.HyperlinkedIdentityField( view_name='dcim-api:device-detail') device_type = NestedDeviceTypeSerializer() device_role = NestedDeviceRoleSerializer() tenant = NestedTenantSerializer(required=False, allow_null=True) platform = NestedPlatformSerializer(required=False, allow_null=True) site = NestedSiteSerializer() location = NestedLocationSerializer(required=False, allow_null=True, default=None) rack = NestedRackSerializer(required=False, allow_null=True) face = ChoiceField(choices=DeviceFaceChoices, allow_blank=True, required=False) status = ChoiceField(choices=DeviceStatusChoices, required=False) primary_ip = NestedIPAddressSerializer(read_only=True) primary_ip4 = NestedIPAddressSerializer(required=False, allow_null=True) primary_ip6 = NestedIPAddressSerializer(required=False, allow_null=True) parent_device = serializers.SerializerMethodField() cluster = NestedClusterSerializer(required=False, allow_null=True) virtual_chassis = NestedVirtualChassisSerializer(required=False, allow_null=True) class Meta: model = Device fields = [ 'id', 'url', 'display', 'name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag', 'site', 'location', 'rack', 'position', 'face', 'parent_device', 'status', 'primary_ip', 'primary_ip4', 'primary_ip6', 'cluster', 'virtual_chassis', 'vc_position', 'vc_priority', 'comments', 'local_context_data', 'tags', 'custom_fields', 'created', 'last_updated', ] validators = [] def validate(self, data): # Validate uniqueness of (rack, position, face) since we omitted the automatically-created validator from Meta. if data.get('rack') and data.get('position') and data.get('face'): validator = UniqueTogetherValidator(queryset=Device.objects.all(), fields=('rack', 'position', 'face')) validator(data, self) # Enforce model validation super().validate(data) return data @swagger_serializer_method(serializer_or_field=NestedDeviceSerializer) def get_parent_device(self, obj): try: device_bay = obj.parent_bay except DeviceBay.DoesNotExist: return None context = {'request': self.context['request']} data = NestedDeviceSerializer(instance=device_bay.device, context=context).data data['device_bay'] = NestedDeviceBaySerializer(instance=device_bay, context=context).data return data
class RackSerializer(PrimaryModelSerializer): url = serializers.HyperlinkedIdentityField( view_name='dcim-api:rack-detail') site = NestedSiteSerializer() location = NestedLocationSerializer(required=False, allow_null=True, default=None) tenant = NestedTenantSerializer(required=False, allow_null=True) status = ChoiceField(choices=RackStatusChoices, required=False) role = NestedRackRoleSerializer(required=False, allow_null=True) type = ChoiceField(choices=RackTypeChoices, allow_blank=True, required=False) width = ChoiceField(choices=RackWidthChoices, required=False) outer_unit = ChoiceField(choices=RackDimensionUnitChoices, allow_blank=True, required=False) device_count = serializers.IntegerField(read_only=True) powerfeed_count = serializers.IntegerField(read_only=True) class Meta: model = Rack fields = [ 'id', 'url', 'display', 'name', 'facility_id', 'site', 'location', 'tenant', 'status', 'role', 'serial', 'asset_tag', 'type', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'device_count', 'powerfeed_count', ] # Omit the UniqueTogetherValidator that would be automatically added to validate (location, facility_id). This # prevents facility_id from being interpreted as a required field. validators = [ UniqueTogetherValidator(queryset=Rack.objects.all(), fields=('location', 'name')) ] def validate(self, data): # Validate uniqueness of (location, facility_id) since we omitted the automatically-created validator from Meta. if data.get('facility_id', None): validator = UniqueTogetherValidator(queryset=Rack.objects.all(), fields=('location', 'facility_id')) validator(data, self) # Enforce model validation super().validate(data) return data
class UserSerializer(serializers.HyperlinkedModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='quser:user-detail') groups = serializers.HyperlinkedRelatedField( help_text='该用户归属的组。一个用户将得到其归属的组的所有权限。', label='组', many=True, queryset=Group.objects.all(), required=False, view_name='quser:group-detail' ) groups_name = serializers.SerializerMethodField() # groups_info = serializers.SerializerMethodField() reset_password_url = serializers.SerializerMethodField() class Meta: model = models.User fields = utils.generate_fields( model, add=['groups_name', 'reset_password_url'], remove=['is_superuser', 'is_staff', 'user_permissions'] ) extra_kwargs = { 'password': { 'write_only': True, 'style': { 'input_type': 'password' }, 'trim_whitespace': False }, 'last_login': { 'read_only': True }, 'date_joined': { 'read_only': True } } def get_groups_name(self, instance): groups_name = list(instance.groups.values_list("name", flat=True)) return ';'.join(groups_name) # def get_groups_info(self, instance): # groups = instance.groups.all() # serializer = GroupListSerializer(groups, many=True, context=self.context) # return serializer.data def get_reset_password_url(self, instance): return reverse( 'quser:user-reset-password', args=(instance.id,), request=self.context.get('request') ) def create(self, validated_data): password = validated_data.pop('password', getattr(settings, 'DEFAULT_ADMIN_PASSWORD', '123456')) # 默认创建的是管理员 validated_data.setdefault('is_staff', True) instance = super().create(validated_data) instance.set_password(password) instance.save() return instance def validate(self, attrs): request = self.context.get('request') if getattr(settings, 'USER_JUST_ONE_GROUP', False) and len(attrs.get('groups', [])) > 1: raise serializers.ValidationError(_('One user can only have one role.')) # 限制用户对自己账号的某些操作 if request and self.instance and self.instance == request.user: if 'groups' in attrs: new_groups = attrs.get('groups') old_groups = list(self.instance.groups.all()) if len(new_groups) != len(old_groups) or set(new_groups) != set(old_groups): raise serializers.ValidationError(_('You can not change your permissions.')) if 'username' in attrs and attrs.get('username') != self.instance.username: raise serializers.ValidationError(_('You can not change your username.')) # 无法直接修改密码,只允许通过重置密码和修改密码接口修改 if self.instance: attrs.pop('password', None) return attrs
class Meta: model = SupplyRequestItem url = serializers.HyperlinkedIdentityField( view_name='supplyrequestitem', lookup_field='id') fields = ('id', 'supply_request', 'item', 'requested_quantity')
class CategorySerializer(BaseCategorySerializer): children = serializers.HyperlinkedIdentityField( view_name="category-child-list", lookup_field="full_slug", lookup_url_kwarg="breadcrumbs", )
class VideoSerializer(serializers.HyperlinkedModelSerializer): """ Serializer to be used for getting and updating Videos. """ # url field should lookup by 'hash key' not the 'pk' url = serializers.HyperlinkedIdentityField(view_name='video-detail', lookup_field='hash_key') owner = UserPublicSerializer(read_only=True) photo_thumbnail = serializers.SerializerMethodField() photo_small_thumbnail = serializers.SerializerMethodField() liked = serializers.SerializerMethodField() new_likes_count = serializers.SerializerMethodField() new_clips_count = serializers.SerializerMethodField() membership_status = serializers.SerializerMethodField() clips = ClipSerializer(many=True, source='get_clips') # Show links to the video's sub-collections that can't be fully embedded users_url = serializers.HyperlinkedIdentityField( view_name='video-user-list', lookup_field='hash_key') class Meta: model = Video fields = ('url', 'hash_key', 'owner', 'title', 'photo_thumbnail', 'photo_small_thumbnail', 'liked', 'likes_count', 'plays_count', 'clips_count', 'duration', 'score', 'new_likes_count', 'new_clips_count', 'membership_status', 'created_at', 'updated_at', 'clips', 'users_url') read_only_fields = ('id', 'hash_key', 'likes_count', 'plays_count', 'clips_count', 'duration', 'score', 'created_at', 'updated_at', 'clips') def get_photo_thumbnail(self, obj): """ Get the absolute URI of the video's photo thumbnail """ return obj.get_photo_thumbnail_url() def get_photo_small_thumbnail(self, obj): """ Get the absolute URI of the video's small photo thumbnail """ return obj.get_photo_small_thumbnail_url() def get_liked(self, obj): """ Determine if the current request user liked the video """ user = self.context['request'].user has_liked = False try: like_activities = obj.prefetched_activity_object_likes has_liked = len(like_activities) > 0 except AttributeError: if user.is_authenticated(): has_liked = Activity.objects.filter( actor_id=user.id, verb='like', object_id=obj.id, object_content_type=ContentType.objects.get_for_model( obj)).exists() return has_liked def get_new_likes_count(self, obj): """ Dummy value to be overwritten in `to_representation` """ return 0 def get_new_clips_count(self, obj): """ Dummy value to be overwritten in `to_representation` """ return 0 def get_membership_status(self, obj): """ Dummy value to be overwritten in `to_representation` """ return VideoUsers.STATUS_NONE def to_representation(self, obj): """ List of object instances -> List of dicts of primitive datatypes. Add the fields: new_likes_count, new_clips_count, membership_status and do it all in 1 query """ ret = super(VideoSerializer, self).to_representation(obj) # check for if we need to override the VideoUsers object stats if 'new_likes_count' not in ret: return ret new_clips_count = 0 new_likes_count = 0 status = VideoUsers.STATUS_NONE user = self.context['request'].user video_user = None try: videousers = obj.prefetched_videousers if len(videousers) == 1: video_user = videousers[0] except AttributeError: if user.is_authenticated(): try: video_user = VideoUsers.objects.get(video_id=obj.id, user_id=user.id) except VideoUsers.DoesNotExist: pass if video_user is not None: new_clips_count = video_user.new_clips_count new_likes_count = video_user.new_likes_count status = video_user.status ret['new_likes_count'] = new_likes_count ret['new_clips_count'] = new_clips_count ret['membership_status'] = status return ret
class Meta: model = TechnologyType url = serializers.HyperlinkedIdentityField(view_name='technologytype', lookup_field='id') fields = ('id', 'url', 'type')
class Meta: model = Team url = serializers.HyperlinkedIdentityField(view_name='team', lookup_field='id') fields = ('id', 'url', 'team_name', 'runnerteam', 'number_of_runners') depth = 2
class NestedProviderSerializer(serializers.ModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='circuits-api:provider-detail') class Meta: model = Provider fields = ['id', 'url', 'name', 'slug']
class PersonSerializer(MinimalPersonSerializer): class Meta: model = people.models.Person fields = ( "id", "url", "versions_url", "history_url", "last_updated", "honorific_prefix", "name", "honorific_suffix", "other_names", "sort_name", "identifiers", "candidacies", "email", "gender", "birth_date", "death_date", "images", "thumbnail", "statement_to_voters", "favourite_biscuit", ) versions_url = serializers.HyperlinkedIdentityField( view_name="person-versions") history_url = serializers.HyperlinkedIdentityField( view_name="person-history") last_updated = serializers.DateTimeField(source="updated_at") identifiers = PersonIdentifierSerializer(many=True, read_only=True, source="tmp_person_identifiers") other_names = OtherNameSerializer(many=True, read_only=True) images = ImageSerializer(many=True, read_only=True, default=[]) email = serializers.SerializerMethodField() candidacies = serializers.SerializerMethodField() statement_to_voters = serializers.CharField(source="biography", allow_blank=True) favourite_biscuit = serializers.CharField(allow_null=True, allow_blank=True) thumbnail = serializers.SerializerMethodField() def get_thumbnail(self, instance): try: image = instance.images.all()[0] except IndexError: return None return SizeLimitedHyperlinkedSorlImageField( "300x300", options={ "crop": "center" }, read_only=True, use_url=True).to_representation(image.image) def get_email(self, obj): return obj.get_email @swagger_serializer_method(serializer_or_field=CandidacyOnPersonSerializer) def get_candidacies(self, obj): qs = obj.memberships.all() return CandidacyOnPersonSerializer(qs, many=True, context={ "request": self.context["request"] }).data
class NestedCircuitSerializer(serializers.ModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuit-detail') class Meta: model = Circuit fields = ['id', 'url', 'cid']
class ProjectSerializer(serializers.HyperlinkedModelSerializer): projectid = serializers.ReadOnlyField(source='id') url = serializers.HyperlinkedIdentityField(view_name='project-detail', lookup_field='pk') owner = serializers.HyperlinkedRelatedField(view_name='user-detail', source='organization', lookup_field='username', queryset=User.objects.all()) created_by = serializers.HyperlinkedRelatedField(view_name='user-detail', lookup_field='username', read_only=True) metadata = JsonField(required=False) starred = serializers.SerializerMethodField('is_starred_project') users = serializers.SerializerMethodField('get_project_permissions') forms = serializers.SerializerMethodField('get_project_forms') public = BooleanField(source='shared') tags = TagListSerializer(read_only=True) num_datasets = serializers.SerializerMethodField() last_submission_date = serializers.SerializerMethodField() class Meta: model = Project exclude = ('organization', 'user_stars') def update(self, instance, validated_data): metadata = JsonField.to_json(validated_data.get('metadata')) if self.partial and metadata: if not isinstance(instance.metadata, dict): instance.metadata = {} instance.metadata.update(metadata) validated_data['metadata'] = instance.metadata return super(ProjectSerializer, self).update(instance, validated_data) def create(self, validated_data): if 'request' in self.context: created_by = self.context['request'].user return Project.objects.create( name=validated_data.get('name'), organization=validated_data.get('organization'), created_by=created_by, metadata=validated_data.get('metadata'), ) def get_project_permissions(self, obj): return get_object_users_with_permissions(obj, serializable=True) @check_obj def get_project_forms(self, obj): xforms_details = obj.projectxform_set.values('xform__pk', 'xform__title') return [{ 'name': form['xform__title'], 'id': form['xform__pk'] } for form in xforms_details] @check_obj def get_num_datasets(self, obj): """Return the number of datasets attached to the object. :param obj: The project to find datasets for. """ return obj.projectxform_set.count() @check_obj def get_last_submission_date(self, obj): """Return the most recent submission date to any of the projects datasets. :param obj: The project to find the last submission date for. """ xform_ids = obj.projectxform_set.values_list('xform', flat=True) last_submission = Instance.objects.\ order_by('-date_created').\ filter(xform_id__in=xform_ids).values_list('date_created', flat=True) # Force explicit serialization to a list as it used to rely on # an implicit one. last_submission = list(last_submission) return last_submission and last_submission[0] def is_starred_project(self, obj): request = self.context['request'] user = request.user user_stars = obj.user_stars.all() if user in user_stars: return True return False
class ClientSerializer(serializers.HyperlinkedModelSerializer): # letter_sub = LetterSubscriptionSerializer(allow_null=True, required=False) # letter_sub = serializers.SerializerMethodField() email = serializers.EmailField( validators=[ UniqueValidator( queryset=Client.objects.all(), message="Client with this email already exists", ) ] ) url = serializers.HyperlinkedIdentityField( view_name="client-detail", lookup_field="_id" ) # def get_letter_sub(self, obj): # return_data = None # print(obj.letter_sub) # if obj.letter_sub is None: # return None # if type(obj.letter_sub) == list: # embedded_list = [] # for item in obj.letter_sub: # embedded_dict = item.__dict__ # for key in list(embedded_dict.keys()): # if key.startswith('_'): # embedded_dict.pop(key) # embedded_list.append(embedded_dict) # return_data = embedded_list # else: # embedded_dict = obj.letter_sub.__dict__ # for key in list(embedded_dict.keys()): # if key.startswith('_'): # embedded_dict.pop(key) # return_data = embedded_dict # return return_data @transaction.atomic() def create(self, validated_data): password = validated_data.pop("password", None) if password and not re.match( r"^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[a-zA-Z]).{8,}$", password ): raise serializers.ValidationError( { "error": """Password should match these criteria - at least 8 characters - must contain at least 1 uppercase letter, 1 lowercase letter, and 1 number - Can contain special characters""" } ) instance = Client.objects.create(**validated_data) if password is not None: instance.set_password(password) instance.save() print(instance) return instance @transaction.atomic() def update(self, instance, validated_data): for attr, value in validated_data.items(): if attr == "password": instance.set_password(value) else: setattr(instance, attr, value) instance.save() return instance class Meta: model = Client exclude = ("user_permissions", "groups") # Since there are no default viewsets for Permissions, Django will try to look up for them # and will throw error "ImproperlyConfigured" # solution is either add your own Permission viewset as mentioned above # or exclude this field lookup_field = "_id"
class Meta: model = CompanyContact url = serializers.HyperlinkedIdentityField(view_name='CompanyContact', lookup_field='id') fields = ('id', 'company_name', 'contact_name', 'contact_phone_number', 'contact_email')
class EntityMinimalSerializer(serializers.HyperlinkedModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='entity-detail') class Meta: model = Entity fields = ['url', 'id', 'name', 'category', 'store']
class AllFieldsSerializer(serializers.ModelSerializer): field_decimal_uncoerced = serializers.DecimalField(source='field_decimal', max_digits=6, decimal_places=3, coerce_to_string=False) field_method_float = serializers.SerializerMethodField() def get_field_method_float(self, obj) -> float: return 1.3456 field_method_object = serializers.SerializerMethodField() def get_field_method_object(self, obj) -> dict: return {'key': 'value'} field_regex = serializers.RegexField(r'^[a-zA-z0-9]{10}\-[a-z]', label='A regex field') field_hidden = serializers.HiddenField(default='') # composite fields field_list = serializers.ListField( child=serializers.FloatField(), min_length=3, max_length=100, ) field_list_serializer = serializers.ListField( child=AuxSerializer(), source='field_list_object', ) # extra related fields field_related_slug = serializers.SlugRelatedField( read_only=True, source='field_foreign', slug_field='id') # type: ignore field_related_string = serializers.StringRelatedField( source='field_foreign') # type: ignore field_related_hyperlink = serializers.HyperlinkedRelatedField( read_only=True, source='field_foreign', view_name='aux-detail') # type: ignore field_identity_hyperlink = serializers.HyperlinkedIdentityField( read_only=True, view_name='allfields-detail') # read only - model traversal field_read_only_nav_uuid = serializers.ReadOnlyField( source='field_foreign.id') field_read_only_nav_uuid_3steps = serializers.ReadOnlyField( source='field_foreign.field_foreign.field_foreign.id', allow_null=True, # force field output even if traversal fails ) field_read_only_model_function_basic = serializers.ReadOnlyField( source='model_function_basic') field_read_only_model_function_model = serializers.ReadOnlyField( source='model_function_model.id') # override default writable bool field with readonly field_bool_override = serializers.ReadOnlyField() field_model_property_float = serializers.ReadOnlyField() field_model_cached_property_float = serializers.ReadOnlyField() field_dict_int = serializers.DictField( child=serializers.IntegerField(), source='field_json', ) # there is a JSON model field for django>=3.1 that would be placed automatically. for <=3.1 we # need to set the field explicitly. defined here for both cases to have consistent ordering. field_json = serializers.JSONField() # traversal of non-model types of complex object field_sub_object_calculated = serializers.ReadOnlyField( source='sub_object.calculated') field_sub_object_nested_calculated = serializers.ReadOnlyField( source='sub_object.nested.calculated') field_sub_object_model_int = serializers.ReadOnlyField( source='sub_object.model_instance.field_int') field_sub_object_cached_calculated = serializers.ReadOnlyField( source='sub_object_cached.calculated') field_sub_object_cached_nested_calculated = serializers.ReadOnlyField( source='sub_object_cached.nested.calculated') field_sub_object_cached_model_int = serializers.ReadOnlyField( source='sub_object_cached.model_instance.field_int') # typing.Optional field_optional_sub_object_calculated = serializers.ReadOnlyField( source='optional_sub_object.calculated', allow_null=True, ) field_sub_object_optional_int = serializers.ReadOnlyField( source='sub_object.optional_int', allow_null=True, ) class Meta: fields = '__all__' model = AllFields
class StudentSerializer(serializers.HyperlinkedModelSerializer): url = serializers.HyperlinkedIdentityField( view_name='university:student-detail', lookup_field='matric_number') user = UserSerializer(read_only=True) # department = DepartmentSerializer() department = serializers.HyperlinkedRelatedField( view_name='university:department-detail', queryset=Department.objects.all(), lookup_field='slug') # courses = CourseSerializer(many=True) courses = serializers.HyperlinkedRelatedField( view_name='university:course-detail', queryset=Course.objects.all(), lookup_field='code', many=True) scores = ScoreSerializer(many=True) class Meta: model = Student fields = ('id', 'url', 'user', 'matric_number', 'department', 'courses', 'scores') @transaction.atomic def create(self, validated_data): user_data = validated_data.pop('user') user = get_user_model().objects.create_user(**user_data) courses = validated_data.pop('courses') scores_data = validated_data.pop('scores') student = Student.objects.create(user=user, **validated_data) if scores_data: # preventing duplicate course scores for a particular student for data in scores_data: score = Score.objects.get_or_create(**data)[0] qs = student.scores.filter(course=score.course) if qs.exists(): student.scores.remove(*qs) student.scores.add(score) # scores = [Score.objects.get_or_create(**data)[0] for data in scores_data] # student.scores.add(*scores) student.courses.add(*courses) return student @transaction.atomic def update(self, instance, validated_data): instance.department = validated_data.get('department', instance.department) courses = validated_data.get('courses', []) if courses: instance.courses.add(*courses) scores_data = validated_data.get('scores', []) if scores_data: for data in scores_data: score = Score.objects.get_or_create(**data)[0] qs = instance.scores.filter(course=score.course) if qs.exists(): instance.scores.remove(*qs) instance.scores.add(score) return instance
class LanguageSerializer(serializers.ModelSerializer): name = serializers.CharField(required=False, max_length=LANGUAGE_NAME_LENGTH) web_url = AbsoluteURLField(source="get_absolute_url", read_only=True) plural = LanguagePluralSerializer(required=False) aliases = serializers.ListField(source="get_aliases_names", read_only=True) statistics_url = serializers.HyperlinkedIdentityField( view_name="api:language-statistics", lookup_field="code") class Meta: model = Language fields = ( "code", "name", "plural", "aliases", "direction", "web_url", "url", "statistics_url", ) extra_kwargs = { "url": { "view_name": "api:language-detail", "lookup_field": "code" }, "code": { "validators": [] }, } @property def is_source_language(self): return (isinstance(self.parent, ProjectSerializer) and self.field_name == "source_language") def validate_code(self, value): check_query = Language.objects.filter(code=value) if not check_query.exists() and self.is_source_language: raise serializers.ValidationError( "Language with this language code was not found.") return value def validate_plural(self, value): if not value and not self.is_source_language: raise serializers.ValidationError("This field is required.") return value def validate_name(self, value): if not value and not self.is_source_language: raise serializers.ValidationError("This field is required.") return value def create(self, validated_data): plural_validated = validated_data.pop("plural", None) if not plural_validated: raise serializers.ValidationError( "No valid plural data was provided.") check_query = Language.objects.filter(code=validated_data.get("code")) if check_query.exists(): raise serializers.ValidationError( "Language with this Language code already exists.") language = Language.objects.create(**validated_data) plural = Plural(language=language, **plural_validated) plural.save() return language def get_value(self, dictionary): if self.is_source_language and "source_language" in dictionary: value = dictionary["source_language"] if isinstance(value, str): return {"code": value} return super().get_value(dictionary)
from rest_framework import serializers from blog.models import Post post_detail_url = serializers.HyperlinkedIdentityField( view_name='api:post-detail', lookup_field='pk') class PostSerializer(serializers.ModelSerializer): detail_url = post_detail_url class Meta: model = Post fields = '__all__' class PostCreateSerializer(serializers.ModelSerializer): detail_url = post_detail_url class Meta: model = Post fields = ['name', 'body', 'image', 'detail_url']