class HyperlinkedRelatedFieldSerializer(Serializer): single = HyperlinkedRelatedField( self_link_view_name="basic-model-relationships", related_link_view_name="basic-model-related", read_only=True, ) many = HyperlinkedRelatedField( self_link_view_name="basic-model-relationships", related_link_view_name="basic-model-related", read_only=True, many=True, ) single_serializer_method = SerializerMethodHyperlinkedRelatedField( self_link_view_name="basic-model-relationships", related_link_view_name="basic-model-related", read_only=True, ) many_serializer_method = SerializerMethodHyperlinkedRelatedField( self_link_view_name="basic-model-relationships", related_link_view_name="basic-model-related", read_only=True, many=True, ) def get_single_serializer_method(self, obj): # pragma: no cover raise NotImplementedError def get_many_serializer_method(self, obj): # pragma: no cover raise NotImplementedError
class UserSerializer(serializers.HyperlinkedModelSerializer): included_serializers = { "organizations": "core.serializers.OrganizationSerializer", "memberships": "core.serializers.MembershipSerializer", } # A User is member of zero or more organizations. organizations = HyperlinkedRelatedField( many=True, read_only=False, allow_null=True, required=False, queryset=Organization.objects.all(), self_link_view_name="user-relationships", related_link_view_name="user-related", ) # A User holds zero or more organization memberships. memberships = HyperlinkedRelatedField( many=True, read_only=True, # Memberships cannot be detached from their user. allow_null=True, required=False, related_link_view_name="user-related", ) class Meta: model = User fields = ( "username", "email", "first_name", "last_name", "organizations", "memberships", "url", )
class OrganizationSerializer(serializers.HyperlinkedModelSerializer): included_serializers = { "users": "core.serializers.UserSerializer", "memberships": "core.serializers.MembershipSerializer", "sites": "core.serializers.SiteSerializer", "nodes": "core.serializers.NodeSerializer", } # An Organization has one or more users as members. users = ResourceRelatedField( many=True, allow_null=True, required=False, queryset=User.objects.all(), related_link_url_kwarg="organization_pk", related_link_view_name="organization-related-users", ) # An Organization operates zero or more sites. sites = HyperlinkedRelatedField( many=True, read_only=True, # Memberships cannot be detached from their organization. allow_null=True, required=False, related_link_url_kwarg="organization_pk", related_link_view_name="organization-related-sites", ) # An Organization is related to its members via Memberships. memberships = HyperlinkedRelatedField( many=True, read_only=True, # Sites cannot be detached from their organization. allow_null=True, required=False, related_link_url_kwarg="organization_pk", related_link_view_name="organization-related-memberships", ) # An Organization operates one or more nodes. nodes = HyperlinkedRelatedField( many=True, read_only=True, # Nodes cannot be detached from their organization. allow_null=True, required=False, related_link_url_kwarg="organization_pk", related_link_view_name="organization-related-nodes", ) class Meta: model = Organization fields = ( "name", "description", "users", "memberships", "sites", "nodes", "url", )
def test_single_hyperlinked_related_field(self): field = HyperlinkedRelatedField( related_link_view_name='entry-blog', related_link_url_kwarg='entry_pk', self_link_view_name='entry-relationships', read_only=True, ) field._context = {'request': self.request, 'view': self.view} field.field_name = 'blog' self.assertRaises(NotImplementedError, field.to_representation, self.entry) self.assertRaises(SkipField, field.get_attribute, self.entry) links_expected = { 'self': 'http://testserver/entries/{}/relationships/blog'.format(self.entry.pk), 'related': 'http://testserver/entries/{}/blog'.format(self.entry.pk) } got = field.get_links(self.entry) self.assertEqual(got, links_expected)
def test_relationship_urls_respect_format_related_links_setting( settings, format_related_links, expected_url_segment): settings.JSON_API_FORMAT_RELATED_LINKS = format_related_links model = BasicModel(text="Some text") field = HyperlinkedRelatedField( self_link_view_name="basic-model-relationships", related_link_view_name="basic-model-related", read_only=True, ) field.field_name = "relatedField_name" expected = { "self": f"/basic_models/{model.pk}/relationships/{expected_url_segment}/", "related": f"/basic_models/{model.pk}/{expected_url_segment}/", } actual = field.get_links(model) assert expected == actual
def test_single_hyperlinked_related_field(self): field = HyperlinkedRelatedField( related_link_view_name="entry-blog", related_link_url_kwarg="entry_pk", self_link_view_name="entry-relationships", read_only=True, ) field._context = {"request": self.request, "view": self.view} field.field_name = "blog" self.assertRaises(NotImplementedError, field.to_representation, self.entry) self.assertRaises(SkipField, field.get_attribute, self.entry) links_expected = { "self": "http://testserver/entries/{}/relationships/blog".format( self.entry.pk), "related": "http://testserver/entries/{}/blog".format(self.entry.pk), } got = field.get_links(self.entry) self.assertEqual(got, links_expected)
class RoomSerializer(serializers.HyperlinkedModelSerializer): related_serializers = { "site": "core.serializers.SiteSerializer", "installations": "core.serializers.RoomNodeInstallationSerializer", } site = ResourceRelatedField( queryset=Site.objects.all(), related_link_url_kwarg="room_pk", related_link_view_name="room-related-site", ) #: A Room contains zero or more node installations. installations = HyperlinkedRelatedField( many=True, read_only=False, allow_null=True, required=False, queryset=RoomNodeInstallation.objects.all(), related_link_url_kwarg="room_pk", related_link_view_name="room-related-installations", ) class Meta: model = Room fields = [ "name", "description", "size_sqm", "height_m", "max_occupancy", "site", "installations", "url", ] def get_owner(self): """Return the owner of the resource, once data is validated.""" site = self.validated_data["site"] owner = site.operator return owner
class SiteSerializer(serializers.HyperlinkedModelSerializer): included_serializers = { "address": "core.serializers.AddressSerializer", "operator": "core.serializers.OrganizationSerializer", "rooms": "core.serializers.RoomSerializer", } address = ResourceRelatedField( queryset=Address.objects.all(), related_link_view_name="site-related" ) operator = ResourceRelatedField( queryset=Organization.objects.all(), related_link_url_kwarg="site_pk", related_link_view_name="site-related-organization", ) #: A Site has zero or more room instances rooms = HyperlinkedRelatedField( many=True, read_only=False, allow_null=True, required=False, queryset=Room.objects.all(), related_link_url_kwarg="site_pk", related_link_view_name="site-related-rooms", ) class Meta: model = Site fields = ("name", "description", "address", "operator", "rooms", "url") class JSONAPIMeta: included_resources = ["address"] def get_owner(self): """Return the owner of the resource, once data is validated.""" return self.validated_data["operator"]
class NodeSerializer(serializers.HyperlinkedModelSerializer): related_serializers = { "protocol": "core.serializers.NodeProtocolSerializer", "model": "core.serializers.NodeModelSerializer", "owner": "core.serializers.OrganizationSerializer", "installations": "core.serializers.RoomNodeInstallationSerializer", } protocol = ResourceRelatedField( queryset=NodeProtocol.objects.all(), related_link_view_name="node-related" ) model = ResourceRelatedField( queryset=NodeModel.objects.all(), related_link_view_name="node-related" ) owner = ResourceRelatedField( queryset=Organization.objects.all(), related_link_view_name="node-related" ) # A Node is installed in one or more rooms over its lifetime. installations = HyperlinkedRelatedField( many=True, read_only=True, related_link_view_name="node-related", ) # Additional fields to merge the node model with its samples. timeseries = serializers.ListField(child=SimpleSampleSerializer(), read_only=True) query_timestamp_s = serializers.IntegerField(read_only=True) sample_count = serializers.IntegerField(read_only=True) from_timestamp_s = serializers.IntegerField(read_only=True) to_timestamp_s = serializers.IntegerField(read_only=True) class Meta: model = Node fields = ( "id", "eui64", "alias", "description", "query_timestamp_s", "from_timestamp_s", "to_timestamp_s", "sample_count", "timeseries", "protocol", "model", "owner", "installations", "url", ) def __init__(self, *args, **kwargs): # Don't pass the "include_timeseries" arg up to the superclass include_timeseries = kwargs.pop("include_timeseries", None) # Instantiate the superclass normally super().__init__(*args, **kwargs) if not include_timeseries: self.fields.pop("timeseries") def get_owner(self): """Return the owner of the resource, once data is validated.""" return self.validated_data["owner"]