authentik.endpoints.api.device_connections

 1from rest_framework.fields import SerializerMethodField
 2
 3from authentik.core.api.utils import ModelSerializer
 4from authentik.endpoints.api.connectors import ConnectorSerializer
 5from authentik.endpoints.api.device_fact_snapshots import DeviceFactSnapshotSerializer
 6from authentik.endpoints.models import Connector, DeviceConnection, DeviceFactSnapshot
 7
 8
 9class DeviceConnectionSerializer(ModelSerializer):
10
11    connector_obj = ConnectorSerializer(source="connector", read_only=True)
12    latest_snapshot = SerializerMethodField(allow_null=True)
13
14    def get_latest_snapshot(self, instance: DeviceConnection) -> DeviceFactSnapshotSerializer:
15        snapshot: DeviceFactSnapshot | None = instance.devicefactsnapshot_set.order_by(
16            "-created"
17        ).first()
18        if not snapshot:
19            return None
20        connector: Connector = Connector.objects.get_subclass(pk=snapshot.connection.connector_id)
21        vendor = connector.controller.vendor_identifier()
22        return DeviceFactSnapshotSerializer(
23            snapshot,
24            context={
25                "vendor": vendor,
26            },
27        ).data
28
29    class Meta:
30        model = DeviceConnection
31        fields = [
32            "device",
33            "connector",
34            "connector_obj",
35            "latest_snapshot",
36        ]
class DeviceConnectionSerializer(authentik.core.api.utils.ModelSerializer):
10class DeviceConnectionSerializer(ModelSerializer):
11
12    connector_obj = ConnectorSerializer(source="connector", read_only=True)
13    latest_snapshot = SerializerMethodField(allow_null=True)
14
15    def get_latest_snapshot(self, instance: DeviceConnection) -> DeviceFactSnapshotSerializer:
16        snapshot: DeviceFactSnapshot | None = instance.devicefactsnapshot_set.order_by(
17            "-created"
18        ).first()
19        if not snapshot:
20            return None
21        connector: Connector = Connector.objects.get_subclass(pk=snapshot.connection.connector_id)
22        vendor = connector.controller.vendor_identifier()
23        return DeviceFactSnapshotSerializer(
24            snapshot,
25            context={
26                "vendor": vendor,
27            },
28        ).data
29
30    class Meta:
31        model = DeviceConnection
32        fields = [
33            "device",
34            "connector",
35            "connector_obj",
36            "latest_snapshot",
37        ]

A ModelSerializer is just a regular Serializer, except that:

  • A set of default fields are automatically populated.
  • A set of default validators are automatically populated.
  • Default .create() and .update() implementations are provided.

The process of automatically determining a set of serializer fields based on the model fields is reasonably complex, but you almost certainly don't need to dig into the implementation.

If the ModelSerializer class doesn't generate the set of fields that you need you should either declare the extra/differing fields explicitly on the serializer class, or simply use a Serializer class.

connector_obj
latest_snapshot
15    def get_latest_snapshot(self, instance: DeviceConnection) -> DeviceFactSnapshotSerializer:
16        snapshot: DeviceFactSnapshot | None = instance.devicefactsnapshot_set.order_by(
17            "-created"
18        ).first()
19        if not snapshot:
20            return None
21        connector: Connector = Connector.objects.get_subclass(pk=snapshot.connection.connector_id)
22        vendor = connector.controller.vendor_identifier()
23        return DeviceFactSnapshotSerializer(
24            snapshot,
25            context={
26                "vendor": vendor,
27            },
28        ).data
class DeviceConnectionSerializer.Meta:
30    class Meta:
31        model = DeviceConnection
32        fields = [
33            "device",
34            "connector",
35            "connector_obj",
36            "latest_snapshot",
37        ]
fields = ['device', 'connector', 'connector_obj', 'latest_snapshot']