serializers.py 34 KB
Newer Older
1
# -*- mode: python; coding: utf-8 -*-
Maël Kervella's avatar
Maël Kervella committed
2 3 4 5
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
6
# Copyright © 2018 Maël Kervella
Maël Kervella's avatar
Maël Kervella committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

22
"""Defines the serializers of the API
Maël Kervella's avatar
Maël Kervella committed
23
"""
24 25

from rest_framework import serializers
26

Maël Kervella's avatar
Maël Kervella committed
27 28 29 30 31 32
import cotisations.models as cotisations
import machines.models as machines
import preferences.models as preferences
import topologie.models as topologie
import users.models as users

33 34
# The namespace used for the API. It must match the namespace used in the
# urlpatterns to include the API URLs.
Maël Kervella's avatar
Maël Kervella committed
35 36 37 38
API_NAMESPACE = 'api'


class NamespacedHRField(serializers.HyperlinkedRelatedField):
39 40 41
    """A `rest_framework.serializers.HyperlinkedRelatedField` subclass to
    automatically prefix view names with the API namespace.
    """
erdnaxe's avatar
erdnaxe committed
42

Maël Kervella's avatar
Maël Kervella committed
43 44 45 46 47 48 49
    def __init__(self, view_name=None, **kwargs):
        if view_name is not None:
            view_name = '%s:%s' % (API_NAMESPACE, view_name)
        super(NamespacedHRField, self).__init__(view_name=view_name, **kwargs)


class NamespacedHIField(serializers.HyperlinkedIdentityField):
50 51 52
    """A `rest_framework.serializers.HyperlinkedIdentityField` subclass to
    automatically prefix view names with teh API namespace.
    """
erdnaxe's avatar
erdnaxe committed
53

Maël Kervella's avatar
Maël Kervella committed
54 55 56 57 58 59 60
    def __init__(self, view_name=None, **kwargs):
        if view_name is not None:
            view_name = '%s:%s' % (API_NAMESPACE, view_name)
        super(NamespacedHIField, self).__init__(view_name=view_name, **kwargs)


class NamespacedHMSerializer(serializers.HyperlinkedModelSerializer):
61 62 63
    """A `rest_framework.serializers.HyperlinkedModelSerializer` subclass to
    automatically prefix view names with the API namespace.
    """
Maël Kervella's avatar
Maël Kervella committed
64 65
    serializer_related_field = NamespacedHRField
    serializer_url_field = NamespacedHIField
66

67

68
# COTISATIONS
69

Maël Kervella's avatar
Maël Kervella committed
70 71

class FactureSerializer(NamespacedHMSerializer):
72 73
    """Serialize `cotisations.models.Facture` objects.
    """
erdnaxe's avatar
erdnaxe committed
74

75
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
76
        model = cotisations.Facture
77 78 79 80
        fields = ('user', 'paiement', 'banque', 'cheque', 'date', 'valid',
                  'control', 'prix_total', 'name', 'api_url')


81 82 83 84 85
class BaseInvoiceSerializer(NamespacedHMSerializer):
    class Meta:
        model = cotisations.BaseInvoice
        fields = ('__all__')

Maël Kervella's avatar
Maël Kervella committed
86
class VenteSerializer(NamespacedHMSerializer):
87 88
    """Serialize `cotisations.models.Vente` objects.
    """
erdnaxe's avatar
erdnaxe committed
89

90
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
91
        model = cotisations.Vente
92 93
        fields = ('facture',
                  'number', 'name', 'prix', 'duration',
94 95 96
                  'type_cotisation', 'prix_total', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
97
class ArticleSerializer(NamespacedHMSerializer):
98 99
    """Serialize `cotisations.models.Article` objects.
    """
erdnaxe's avatar
erdnaxe committed
100

101
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
102
        model = cotisations.Article
103 104 105 106
        fields = ('name', 'prix', 'duration', 'type_user',
                  'type_cotisation', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
107
class BanqueSerializer(NamespacedHMSerializer):
108 109
    """Serialize `cotisations.models.Banque` objects.
    """
erdnaxe's avatar
erdnaxe committed
110

111
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
112
        model = cotisations.Banque
113 114 115
        fields = ('name', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
116
class PaiementSerializer(NamespacedHMSerializer):
117 118
    """Serialize `cotisations.models.Paiement` objects.
    """
erdnaxe's avatar
erdnaxe committed
119

120
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
121
        model = cotisations.Paiement
122
        fields = ('moyen', 'api_url')
123 124


Maël Kervella's avatar
Maël Kervella committed
125
class CotisationSerializer(NamespacedHMSerializer):
126 127
    """Serialize `cotisations.models.Cotisation` objects.
    """
erdnaxe's avatar
erdnaxe committed
128

129
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
130
        model = cotisations.Cotisation
131 132 133 134
        fields = ('vente', 'type_cotisation', 'date_start', 'date_end',
                  'api_url')


135
# MACHINES
136 137


Maël Kervella's avatar
Maël Kervella committed
138
class MachineSerializer(NamespacedHMSerializer):
139 140
    """Serialize `machines.models.Machine` objects.
    """
erdnaxe's avatar
erdnaxe committed
141

142
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
143
        model = machines.Machine
144 145 146
        fields = ('user', 'name', 'active', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
147
class MachineTypeSerializer(NamespacedHMSerializer):
148 149
    """Serialize `machines.models.MachineType` objects.
    """
erdnaxe's avatar
erdnaxe committed
150

151
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
152
        model = machines.MachineType
153 154 155
        fields = ('type', 'ip_type', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
156
class IpTypeSerializer(NamespacedHMSerializer):
157 158
    """Serialize `machines.models.IpType` objects.
    """
erdnaxe's avatar
erdnaxe committed
159

160
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
161
        model = machines.IpType
162 163 164 165 166
        fields = ('type', 'extension', 'need_infra', 'domaine_ip_start',
                  'domaine_ip_stop', 'prefix_v6', 'vlan', 'ouverture_ports',
                  'api_url')


Maël Kervella's avatar
Maël Kervella committed
167
class VlanSerializer(NamespacedHMSerializer):
168 169
    """Serialize `machines.models.Vlan` objects.
    """
erdnaxe's avatar
erdnaxe committed
170

171
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
172
        model = machines.Vlan
173 174
        fields = ('vlan_id', 'name', 'comment', 'arp_protect', 'dhcp_snooping',
                  'dhcpv6_snooping', 'igmp', 'mld', 'api_url')
175 176


Maël Kervella's avatar
Maël Kervella committed
177
class NasSerializer(NamespacedHMSerializer):
178 179
    """Serialize `machines.models.Nas` objects.
    """
erdnaxe's avatar
erdnaxe committed
180

181
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
182
        model = machines.Nas
183 184 185 186
        fields = ('name', 'nas_type', 'machine_type', 'port_access_mode',
                  'autocapture_mac', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
187
class SOASerializer(NamespacedHMSerializer):
188 189
    """Serialize `machines.models.SOA` objects.
    """
erdnaxe's avatar
erdnaxe committed
190

191
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
192
        model = machines.SOA
193 194 195 196
        fields = ('name', 'mail', 'refresh', 'retry', 'expire', 'ttl',
                  'api_url')


Maël Kervella's avatar
Maël Kervella committed
197
class ExtensionSerializer(NamespacedHMSerializer):
198 199
    """Serialize `machines.models.Extension` objects.
    """
erdnaxe's avatar
erdnaxe committed
200

201
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
202
        model = machines.Extension
203 204 205 206
        fields = ('name', 'need_infra', 'origin', 'origin_v6', 'soa',
                  'api_url')


Maël Kervella's avatar
Maël Kervella committed
207
class MxSerializer(NamespacedHMSerializer):
208 209
    """Serialize `machines.models.Mx` objects.
    """
erdnaxe's avatar
erdnaxe committed
210

211
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
212
        model = machines.Mx
213 214 215
        fields = ('zone', 'priority', 'name', 'api_url')


216 217 218
class DNameSerializer(NamespacedHMSerializer):
    """Serialize `machines.models.DName` objects.
    """
erdnaxe's avatar
erdnaxe committed
219

220 221 222 223
    class Meta:
        model = machines.DName
        fields = ('zone', 'alias', 'api_url')

erdnaxe's avatar
erdnaxe committed
224

Maël Kervella's avatar
Maël Kervella committed
225
class NsSerializer(NamespacedHMSerializer):
226 227
    """Serialize `machines.models.Ns` objects.
    """
erdnaxe's avatar
erdnaxe committed
228

229
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
230
        model = machines.Ns
231 232 233
        fields = ('zone', 'ns', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
234
class TxtSerializer(NamespacedHMSerializer):
235 236
    """Serialize `machines.models.Txt` objects.
    """
erdnaxe's avatar
erdnaxe committed
237

238
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
239
        model = machines.Txt
240 241 242
        fields = ('zone', 'field1', 'field2', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
243
class SrvSerializer(NamespacedHMSerializer):
244 245
    """Serialize `machines.models.Srv` objects.
    """
erdnaxe's avatar
erdnaxe committed
246

247
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
248
        model = machines.Srv
249 250 251
        fields = ('service', 'protocole', 'extension', 'ttl', 'priority',
                  'weight', 'port', 'target', 'api_url')

erdnaxe's avatar
erdnaxe committed
252

253 254 255
class SshFpSerializer(NamespacedHMSerializer):
    """Serialize `machines.models.SSHFP` objects.
    """
erdnaxe's avatar
erdnaxe committed
256

257 258 259 260
    class Meta:
        model = machines.SshFp
        field = ('machine', 'pub_key_entry', 'algo', 'comment', 'api_url')

261

Maël Kervella's avatar
Maël Kervella committed
262
class InterfaceSerializer(NamespacedHMSerializer):
263 264
    """Serialize `machines.models.Interface` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
265
    mac_address = serializers.CharField()
266 267 268
    active = serializers.BooleanField(source='is_active')

    class Meta:
Maël Kervella's avatar
Maël Kervella committed
269
        model = machines.Interface
270 271 272 273
        fields = ('ipv4', 'mac_address', 'machine', 'type', 'details',
                  'port_lists', 'active', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
274
class Ipv6ListSerializer(NamespacedHMSerializer):
275 276
    """Serialize `machines.models.Ipv6List` objects.
    """
erdnaxe's avatar
erdnaxe committed
277

278
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
279
        model = machines.Ipv6List
280
        fields = ('ipv6', 'interface', 'slaac_ip', 'api_url')
281 282


Maël Kervella's avatar
Maël Kervella committed
283
class DomainSerializer(NamespacedHMSerializer):
284 285
    """Serialize `machines.models.Domain` objects.
    """
erdnaxe's avatar
erdnaxe committed
286

287
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
288
        model = machines.Domain
289 290 291 292
        fields = ('interface_parent', 'name', 'extension', 'cname',
                  'api_url')


Maël Kervella's avatar
Maël Kervella committed
293
class IpListSerializer(NamespacedHMSerializer):
294 295
    """Serialize `machines.models.IpList` objects.
    """
erdnaxe's avatar
erdnaxe committed
296

297
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
298
        model = machines.IpList
299 300 301
        fields = ('ipv4', 'ip_type', 'need_infra', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
302
class ServiceSerializer(NamespacedHMSerializer):
303 304
    """Serialize `machines.models.Service` objects.
    """
erdnaxe's avatar
erdnaxe committed
305

306
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
307
        model = machines.Service
308 309 310 311
        fields = ('service_type', 'min_time_regen', 'regular_time_regen',
                  'servers', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
312
class ServiceLinkSerializer(NamespacedHMSerializer):
313 314
    """Serialize `machines.models.Service_link` objects.
    """
erdnaxe's avatar
erdnaxe committed
315

316
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
317
        model = machines.Service_link
318 319
        fields = ('service', 'server', 'last_regen', 'asked_regen',
                  'need_regen', 'api_url')
Maël Kervella's avatar
Maël Kervella committed
320 321 322
        extra_kwargs = {
            'api_url': {'view_name': 'servicelink-detail'}
        }
323 324


Maël Kervella's avatar
Maël Kervella committed
325
class OuverturePortListSerializer(NamespacedHMSerializer):
326 327
    """Serialize `machines.models.OuverturePortList` objects.
    """
328 329 330 331 332
    tcp_ports_in = NamespacedHRField(view_name='ouvertureport-detail', many=True, read_only=True)
    udp_ports_in = NamespacedHRField(view_name='ouvertureport-detail', many=True, read_only=True)
    tcp_ports_out = NamespacedHRField(view_name='ouvertureport-detail', many=True, read_only=True)
    udp_ports_out = NamespacedHRField(view_name='ouvertureport-detail', many=True, read_only=True)

333
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
334
        model = machines.OuverturePortList
335 336 337 338
        fields = ('name', 'tcp_ports_in', 'udp_ports_in', 'tcp_ports_out',
                  'udp_ports_out', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
339
class OuverturePortSerializer(NamespacedHMSerializer):
340 341
    """Serialize `machines.models.OuverturePort` objects.
    """
erdnaxe's avatar
erdnaxe committed
342

343
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
344
        model = machines.OuverturePort
345 346 347
        fields = ('begin', 'end', 'port_list', 'protocole', 'io', 'api_url')


348 349 350 351 352 353 354 355 356 357
class RoleSerializer(NamespacedHMSerializer):
    """Serialize `machines.models.OuverturePort` objects.
    """
    servers = InterfaceSerializer(read_only=True, many=True)

    class Meta:
        model = machines.Role
        fields = ('role_type', 'servers', 'api_url')


358
# PREFERENCES
359 360


361
class OptionalUserSerializer(NamespacedHMSerializer):
362 363
    """Serialize `preferences.models.OptionalUser` objects.
    """
364
    tel_mandatory = serializers.BooleanField(source='is_tel_mandatory')
365
    shell_default = serializers.StringRelatedField()
366 367 368

    class Meta:
        model = preferences.OptionalUser
369
        fields = ('tel_mandatory', 'gpg_fingerprint',
370 371 372 373
                  'all_can_create_club', 'self_adhesion', 'shell_default',
                  'self_change_shell', 'local_email_accounts_enabled', 'local_email_domain',
                  'max_email_address',
        )
374 375 376


class OptionalMachineSerializer(NamespacedHMSerializer):
377 378
    """Serialize `preferences.models.OptionalMachine` objects.
    """
erdnaxe's avatar
erdnaxe committed
379

380 381 382 383 384 385 386 387
    class Meta:
        model = preferences.OptionalMachine
        fields = ('password_machine', 'max_lambdauser_interfaces',
                  'max_lambdauser_aliases', 'ipv6_mode', 'create_machine',
                  'ipv6')


class OptionalTopologieSerializer(NamespacedHMSerializer):
388 389
    """Serialize `preferences.models.OptionalTopologie` objects.
    """
detraz's avatar
detraz committed
390
    switchs_management_interface_ip = serializers.CharField()
391

392 393
    class Meta:
        model = preferences.OptionalTopologie
394
        fields = ('switchs_ip_type', 'switchs_web_management',
Gabriel Detraz's avatar
Gabriel Detraz committed
395 396 397
                  'switchs_web_management_ssl', 'switchs_rest_management',
                  'switchs_management_utils', 'switchs_management_interface_ip',
                  'provision_switchs_enabled', 'switchs_provision', 'switchs_management_sftp_creds')
398 399


400 401 402 403 404 405 406 407 408 409 410 411 412
class RadiusOptionSerializer(NamespacedHMSerializer):
    """Serialize `preferences.models.RadiusOption` objects
    """

    class Meta:
        model = preferences.RadiusOption
        fields = ('radius_general_policy', 'unknown_machine',
                'unknown_machine_vlan', 'unknown_port',
                'unknown_port_vlan', 'unknown_room', 'unknown_room_vlan',
                'non_member', 'non_member_vlan', 'banned', 'banned_vlan',
                'vlan_decision_ok')


413
class GeneralOptionSerializer(NamespacedHMSerializer):
414 415
    """Serialize `preferences.models.GeneralOption` objects.
    """
erdnaxe's avatar
erdnaxe committed
416

417 418
    class Meta:
        model = preferences.GeneralOption
419 420 421
        fields = ('general_message_fr', 'general_message_en',
                  'search_display_page', 'pagination_number',
                  'pagination_large_number', 'req_expire_hrs',
422 423
                  'site_name', 'main_site_url', 'email_from',
                  'GTU_sum_up', 'GTU')
424

425
class HomeServiceSerializer(NamespacedHMSerializer):
426 427
    """Serialize `preferences.models.Service` objects.
    """
erdnaxe's avatar
erdnaxe committed
428

429 430 431
    class Meta:
        model = preferences.Service
        fields = ('name', 'url', 'description', 'image', 'api_url')
432 433 434
        extra_kwargs = {
            'api_url': {'view_name': 'homeservice-detail'}
        }
435 436 437


class AssoOptionSerializer(NamespacedHMSerializer):
438 439
    """Serialize `preferences.models.AssoOption` objects.
    """
erdnaxe's avatar
erdnaxe committed
440

441 442 443
    class Meta:
        model = preferences.AssoOption
        fields = ('name', 'siret', 'adresse1', 'adresse2', 'contact',
444
                  'telephone', 'pseudo', 'utilisateur_asso', 'description')
445 446 447


class HomeOptionSerializer(NamespacedHMSerializer):
448 449
    """Serialize `preferences.models.HomeOption` objects.
    """
erdnaxe's avatar
erdnaxe committed
450

451 452 453 454 455 456
    class Meta:
        model = preferences.HomeOption
        fields = ('facebook_url', 'twitter_url', 'twitter_account_name')


class MailMessageOptionSerializer(NamespacedHMSerializer):
457 458
    """Serialize `preferences.models.MailMessageOption` objects.
    """
erdnaxe's avatar
erdnaxe committed
459

460 461 462
    class Meta:
        model = preferences.MailMessageOption
        fields = ('welcome_mail_fr', 'welcome_mail_en')
463 464


465
# TOPOLOGIE
466 467


Maël Kervella's avatar
Maël Kervella committed
468
class StackSerializer(NamespacedHMSerializer):
469 470
    """Serialize `topologie.models.Stack` objects
    """
erdnaxe's avatar
erdnaxe committed
471

472
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
473
        model = topologie.Stack
474 475 476 477
        fields = ('name', 'stack_id', 'details', 'member_id_min',
                  'member_id_max', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
478
class AccessPointSerializer(NamespacedHMSerializer):
479 480
    """Serialize `topologie.models.AccessPoint` objects
    """
erdnaxe's avatar
erdnaxe committed
481

482
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
483
        model = topologie.AccessPoint
484 485 486
        fields = ('user', 'name', 'active', 'location', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
487
class SwitchSerializer(NamespacedHMSerializer):
488 489
    """Serialize `topologie.models.Switch` objects
    """
490
    port_amount = serializers.IntegerField(source='number')
erdnaxe's avatar
erdnaxe committed
491

492
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
493
        model = topologie.Switch
Maël Kervella's avatar
Maël Kervella committed
494 495
        fields = ('user', 'name', 'active', 'port_amount', 'stack',
                  'stack_member_id', 'model', 'switchbay', 'api_url')
496 497


498 499 500
class ServerSerializer(NamespacedHMSerializer):
    """Serialize `topologie.models.Server` objects
    """
erdnaxe's avatar
erdnaxe committed
501

502 503 504 505 506
    class Meta:
        model = topologie.Server
        fields = ('user', 'name', 'active', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
507
class ModelSwitchSerializer(NamespacedHMSerializer):
508 509
    """Serialize `topologie.models.ModelSwitch` objects
    """
erdnaxe's avatar
erdnaxe committed
510

511
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
512
        model = topologie.ModelSwitch
513 514 515
        fields = ('reference', 'constructor', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
516
class ConstructorSwitchSerializer(NamespacedHMSerializer):
517 518
    """Serialize `topologie.models.ConstructorSwitch` objects
    """
erdnaxe's avatar
erdnaxe committed
519

520
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
521
        model = topologie.ConstructorSwitch
522 523 524
        fields = ('name', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
525
class SwitchBaySerializer(NamespacedHMSerializer):
526 527
    """Serialize `topologie.models.SwitchBay` objects
    """
erdnaxe's avatar
erdnaxe committed
528

529
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
530
        model = topologie.SwitchBay
531 532 533
        fields = ('name', 'building', 'info', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
534
class BuildingSerializer(NamespacedHMSerializer):
535 536
    """Serialize `topologie.models.Building` objects
    """
erdnaxe's avatar
erdnaxe committed
537

538
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
539
        model = topologie.Building
540 541 542
        fields = ('name', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
543
class SwitchPortSerializer(NamespacedHMSerializer):
544 545
    """Serialize `topologie.models.Port` objects
    """
546

547
    get_port_profile = NamespacedHIField(view_name='portprofile-detail', read_only=True)
548

549
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
550
        model = topologie.Port
551
        fields = ('switch', 'port', 'room', 'machine_interface', 'related',
552
                  'custom_profile', 'state', 'get_port_profile', 'details', 'api_url')
Maël Kervella's avatar
Maël Kervella committed
553 554
        extra_kwargs = {
            'related': {'view_name': 'switchport-detail'},
555
            'api_url': {'view_name': 'switchport-detail'},
Maël Kervella's avatar
Maël Kervella committed
556
        }
557 558


559 560 561 562 563
class PortProfileSerializer(NamespacedHMSerializer):
    """Serialize `topologie.models.Room` objects
    """
    class Meta:
        model = topologie.PortProfile
erdnaxe's avatar
erdnaxe committed
564
        fields = ('name', 'profil_default', 'vlan_untagged', 'vlan_tagged',
565 566 567 568 569
                  'radius_type', 'radius_mode', 'speed', 'mac_limit', 'flow_control',
                  'dhcp_snooping', 'dhcpv6_snooping', 'dhcpv6_snooping', 'arp_protect',
                  'ra_guard', 'loop_protect', 'api_url')


Maël Kervella's avatar
Maël Kervella committed
570
class RoomSerializer(NamespacedHMSerializer):
571 572
    """Serialize `topologie.models.Room` objects
    """
erdnaxe's avatar
erdnaxe committed
573

574
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
575
        model = topologie.Room
576 577 578
        fields = ('name', 'details', 'api_url')


579 580 581 582 583 584 585 586 587 588 589 590
class PortProfileSerializer(NamespacedHMSerializer):
    vlan_untagged = VlanSerializer(read_only=True)

    class Meta:
        model = topologie.PortProfile
        fields = ('name', 'profil_default', 'vlan_untagged', 'vlan_tagged',
                  'radius_type', 'radius_mode', 'speed', 'mac_limit',
                  'flow_control', 'dhcp_snooping', 'dhcpv6_snooping',
                  'arp_protect', 'ra_guard', 'loop_protect', 'vlan_untagged',
                  'vlan_tagged')


591
# USERS
592

593

Maël Kervella's avatar
Maël Kervella committed
594
class UserSerializer(NamespacedHMSerializer):
595 596
    """Serialize `users.models.User` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
597 598
    access = serializers.BooleanField(source='has_access')
    uid = serializers.IntegerField(source='uid_number')
599 600

    class Meta:
Maël Kervella's avatar
Maël Kervella committed
601
        model = users.User
602 603
        fields = ('surname', 'pseudo', 'email', 'local_email_redirect',
                  'local_email_enabled', 'school', 'shell', 'comment',
Maël Kervella's avatar
Maël Kervella committed
604 605 606 607 608
                  'state', 'registered', 'telephone', 'solde', 'access',
                  'end_access', 'uid', 'class_name', 'api_url')
        extra_kwargs = {
            'shell': {'view_name': 'shell-detail'}
        }
609

610

Maël Kervella's avatar
Maël Kervella committed
611
class ClubSerializer(NamespacedHMSerializer):
612 613
    """Serialize `users.models.Club` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
614 615 616
    name = serializers.CharField(source='surname')
    access = serializers.BooleanField(source='has_access')
    uid = serializers.IntegerField(source='uid_number')
617 618

    class Meta:
Maël Kervella's avatar
Maël Kervella committed
619
        model = users.Club
620 621
        fields = ('name', 'pseudo', 'email', 'local_email_redirect',
                  'local_email_enabled', 'school', 'shell', 'comment',
Maël Kervella's avatar
Maël Kervella committed
622
                  'state', 'registered', 'telephone', 'solde', 'room',
Maël Kervella's avatar
Maël Kervella committed
623 624
                  'access', 'end_access', 'administrators', 'members',
                  'mailing', 'uid', 'api_url')
Maël Kervella's avatar
Maël Kervella committed
625 626 627
        extra_kwargs = {
            'shell': {'view_name': 'shell-detail'}
        }
628 629


Maël Kervella's avatar
Maël Kervella committed
630
class AdherentSerializer(NamespacedHMSerializer):
631 632
    """Serialize `users.models.Adherent` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
633 634
    access = serializers.BooleanField(source='has_access')
    uid = serializers.IntegerField(source='uid_number')
635

636
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
637
        model = users.Adherent
638 639 640
        fields = ('name', 'surname', 'pseudo', 'email', 'local_email_redirect',
                  'local_email_enabled', 'school', 'shell', 'comment',
                  'state', 'registered', 'telephone', 'room', 'solde',
erdnaxe's avatar
erdnaxe committed
641
                  'access', 'end_access', 'uid', 'api_url', 'gid')
Maël Kervella's avatar
Maël Kervella committed
642 643 644
        extra_kwargs = {
            'shell': {'view_name': 'shell-detail'}
        }
645

erdnaxe's avatar
erdnaxe committed
646

detraz's avatar
detraz committed
647 648
class BasicUserSerializer(NamespacedHMSerializer):
    """Serialize 'users.models.User' minimal infos"""
649 650 651 652 653 654
    uid = serializers.IntegerField(source='uid_number')
    gid = serializers.IntegerField(source='gid_number')

    class Meta:
        model = users.User
        fields = ('pseudo', 'uid', 'gid')
655

erdnaxe's avatar
erdnaxe committed
656

Maël Kervella's avatar
Maël Kervella committed
657
class ServiceUserSerializer(NamespacedHMSerializer):
658 659
    """Serialize `users.models.ServiceUser` objects.
    """
erdnaxe's avatar
erdnaxe committed
660

661
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
662
        model = users.ServiceUser
Maël Kervella's avatar
Maël Kervella committed
663
        fields = ('pseudo', 'access_group', 'comment', 'api_url')
664 665


Maël Kervella's avatar
Maël Kervella committed
666
class SchoolSerializer(NamespacedHMSerializer):
667 668
    """Serialize `users.models.School` objects.
    """
erdnaxe's avatar
erdnaxe committed
669

670
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
671
        model = users.School
Maël Kervella's avatar
Maël Kervella committed
672
        fields = ('name', 'api_url')
673 674


Maël Kervella's avatar
Maël Kervella committed
675
class ListRightSerializer(NamespacedHMSerializer):
676 677
    """Serialize `users.models.ListRight` objects.
    """
erdnaxe's avatar
erdnaxe committed
678

679
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
680
        model = users.ListRight
Maël Kervella's avatar
Maël Kervella committed
681
        fields = ('unix_name', 'gid', 'critical', 'details', 'api_url')
682 683


Maël Kervella's avatar
Maël Kervella committed
684
class ShellSerializer(NamespacedHMSerializer):
685 686
    """Serialize `users.models.ListShell` objects.
    """
erdnaxe's avatar
erdnaxe committed
687

688
    class Meta:
Maël Kervella's avatar
Maël Kervella committed
689
        model = users.ListShell
Maël Kervella's avatar
Maël Kervella committed
690
        fields = ('shell', 'api_url')
Maël Kervella's avatar
Maël Kervella committed
691 692 693
        extra_kwargs = {
            'api_url': {'view_name': 'shell-detail'}
        }
694 695


Maël Kervella's avatar
Maël Kervella committed
696
class BanSerializer(NamespacedHMSerializer):
697 698
    """Serialize `users.models.Ban` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
699
    active = serializers.BooleanField(source='is_active')
700 701

    class Meta:
Maël Kervella's avatar
Maël Kervella committed
702
        model = users.Ban
Maël Kervella's avatar
Maël Kervella committed
703 704
        fields = ('user', 'raison', 'date_start', 'date_end', 'state',
                  'active', 'api_url')
705 706


Maël Kervella's avatar
Maël Kervella committed
707
class WhitelistSerializer(NamespacedHMSerializer):
708 709
    """Serialize `users.models.Whitelist` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
710
    active = serializers.BooleanField(source='is_active')
711 712

    class Meta:
Maël Kervella's avatar
Maël Kervella committed
713
        model = users.Whitelist
Maël Kervella's avatar
Maël Kervella committed
714
        fields = ('user', 'raison', 'date_start', 'date_end', 'active', 'api_url')
715 716


717 718
class EMailAddressSerializer(NamespacedHMSerializer):
    """Serialize `users.models.EMailAddress` objects.
719
    """
720
    user = serializers.CharField(source='user.pseudo', read_only=True)
erdnaxe's avatar
erdnaxe committed
721

722
    class Meta:
723
        model = users.EMailAddress
724
        fields = ('user', 'local_part', 'complete_email_address', 'api_url')
725 726


727
# SERVICE REGEN
728 729 730


class ServiceRegenSerializer(NamespacedHMSerializer):
731 732
    """Serialize the data about the services to regen.
    """
733 734
    hostname = serializers.CharField(source='server.domain.name', read_only=True)
    service_name = serializers.CharField(source='service.service_type', read_only=True)
735
    need_regen = serializers.BooleanField()
736 737 738 739 740

    class Meta:
        model = machines.Service_link
        fields = ('hostname', 'service_name', 'need_regen', 'api_url')
        extra_kwargs = {
741
            'api_url': {'view_name': 'serviceregen-detail'}
742
        }
743

744 745
# Switches et ports

746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770
class InterfaceVlanSerializer(NamespacedHMSerializer):
    domain = serializers.CharField(read_only=True)
    ipv4 = serializers.CharField(read_only=True)
    ipv6 = Ipv6ListSerializer(read_only=True, many=True)
    vlan_id = serializers.IntegerField(source='type.ip_type.vlan.vlan_id', read_only=True)

    class Meta:
        model = machines.Interface
        fields = ('ipv4', 'ipv6', 'domain', 'vlan_id')

class InterfaceRoleSerializer(NamespacedHMSerializer):
    interface = InterfaceVlanSerializer(source='machine.interface_set', read_only=True, many=True)

    class Meta:
        model = machines.Interface
        fields = ('interface',)


class RoleSerializer(NamespacedHMSerializer):
    """Serialize `machines.models.OuverturePort` objects.
    """
    servers = InterfaceRoleSerializer(read_only=True, many=True)

    class Meta:
        model = machines.Role
771
        fields = ('role_type', 'servers', 'specific_role')
772 773


774 775 776
class VlanPortSerializer(NamespacedHMSerializer):
    class Meta:
        model = machines.Vlan
erdnaxe's avatar
erdnaxe committed
777
        fields = ('vlan_id', 'name')
778 779


780
class ProfilSerializer(NamespacedHMSerializer):
781 782 783
    vlan_untagged = VlanSerializer(read_only=True)
    vlan_tagged = VlanPortSerializer(read_only=True, many=True)

784 785
    class Meta:
        model = topologie.PortProfile
786
        fields = ('name', 'profil_default', 'vlan_untagged', 'vlan_tagged', 'radius_type', 'radius_mode', 'speed', 'mac_limit', 'flow_control', 'dhcp_snooping', 'dhcpv6_snooping', 'arp_protect', 'ra_guard', 'loop_protect', 'vlan_untagged', 'vlan_tagged')
787 788 789


class ModelSwitchSerializer(NamespacedHMSerializer):
790 791
    constructor = serializers.CharField(read_only=True)

792 793
    class Meta:
        model = topologie.ModelSwitch
794
        fields = ('reference', 'firmware', 'constructor')
795 796 797 798 799 800 801 802 803 804 805


class SwitchBaySerializer(NamespacedHMSerializer):
    class Meta:
        model = topologie.SwitchBay
        fields = ('name',)


class PortsSerializer(NamespacedHMSerializer):
    """Serialize `machines.models.Ipv6List` objects.
    """
806
    get_port_profile = ProfilSerializer(read_only=True)
807

808

809 810
    class Meta:
        model = topologie.Port
811
        fields = ('state', 'port', 'pretty_name', 'get_port_profile')
812 813


814

815 816 817 818 819 820
class SwitchPortSerializer(serializers.ModelSerializer):
    """Serialize the data about the switches"""
    ports = PortsSerializer(many=True, read_only=True)
    model = ModelSwitchSerializer(read_only=True)
    switchbay = SwitchBaySerializer(read_only=True)

821

822 823
    class Meta:
        model = topologie.Switch
824
        fields = ('short_name', 'model', 'switchbay', 'ports', 'ipv4', 'ipv6',
825
                  'interfaces_subnet', 'interfaces6_subnet', 'automatic_provision', 'rest_enabled',
826 827
                  'web_management_enabled', 'get_radius_key_value', 'get_management_cred_value',
                  'list_modules')
828

829 830 831 832
# LOCAL EMAILS


class LocalEmailUsersSerializer(NamespacedHMSerializer):
833
    email_address = EMailAddressSerializer(
834 835 836
        read_only=True,
        many=True
    )
837 838 839

    class Meta:
        model = users.User
840
        fields = ('local_email_enabled', 'local_email_redirect',
841
                  'email_address', 'email')
842 843


erdnaxe's avatar
erdnaxe committed
844
# Firewall
845 846 847 848

class FirewallPortListSerializer(serializers.ModelSerializer):
    class Meta:
        model = machines.OuverturePort
849
        fields = ('begin', 'end', 'protocole', 'io', 'show_port')
850

erdnaxe's avatar
erdnaxe committed
851

852 853 854 855 856 857 858 859 860 861
class FirewallOuverturePortListSerializer(serializers.ModelSerializer):
    tcp_ports_in = FirewallPortListSerializer(many=True, read_only=True)
    udp_ports_in = FirewallPortListSerializer(many=True, read_only=True)
    tcp_ports_out = FirewallPortListSerializer(many=True, read_only=True)
    udp_ports_out = FirewallPortListSerializer(many=True, read_only=True)

    class Meta:
        model = machines.OuverturePortList
        fields = ('tcp_ports_in', 'udp_ports_in', 'tcp_ports_out', 'udp_ports_out')

erdnaxe's avatar
erdnaxe committed
862

863 864 865 866 867
class SubnetPortsOpenSerializer(serializers.ModelSerializer):
    ouverture_ports = FirewallOuverturePortListSerializer(read_only=True)

    class Meta:
        model = machines.IpType
868
        fields = ('type', 'domaine_ip_start', 'domaine_ip_stop', 'complete_prefixv6', 'ouverture_ports')
869

erdnaxe's avatar
erdnaxe committed
870

871 872 873 874 875 876 877 878 879
class InterfacePortsOpenSerializer(serializers.ModelSerializer):
    port_lists = FirewallOuverturePortListSerializer(read_only=True, many=True)
    ipv4 = serializers.CharField(source='ipv4.ipv4', read_only=True)
    ipv6 = Ipv6ListSerializer(many=True, read_only=True)

    class Meta:
        model = machines.Interface
        fields = ('port_lists', 'ipv4', 'ipv6')

erdnaxe's avatar
erdnaxe committed
880

881 882 883 884
# DHCP


class HostMacIpSerializer(serializers.ModelSerializer):
885 886 887
    """Serialize the data about the hostname-ipv4-mac address association
    to build the DHCP lease files.
    """
888 889
    hostname = serializers.CharField(source='domain.name', read_only=True)
    extension = serializers.CharField(source='domain.extension.name', read_only=True)
890
    mac_address = serializers.CharField(read_only=True)
891 892 893 894 895
    ipv4 = serializers.CharField(source='ipv4.ipv4', read_only=True)

    class Meta:
        model = machines.Interface
        fields = ('hostname', 'extension', 'mac_address', 'ipv4')
896 897 898 899 900 901


# DNS


class SOARecordSerializer(SOASerializer):
902 903 904
    """Serialize `machines.models.SOA` objects with the data needed to
    generate a SOA DNS record.
    """
erdnaxe's avatar
erdnaxe committed
905

906 907 908 909 910 911
    class Meta:
        model = machines.SOA
        fields = ('name', 'mail', 'refresh', 'retry', 'expire', 'ttl')


class OriginV4RecordSerializer(IpListSerializer):
912 913 914
    """Serialize `machines.models.IpList` objects with the data needed to
    generate an IPv4 Origin DNS record.
    """
erdnaxe's avatar
erdnaxe committed
915

916 917 918 919 920
    class Meta(IpListSerializer.Meta):
        fields = ('ipv4',)


class NSRecordSerializer(NsSerializer):
921 922 923
    """Serialize `machines.models.Ns` objects with the data needed to
    generate a NS DNS record.
    """
924
    target = serializers.CharField(source='ns', read_only=True)
925 926 927 928 929 930

    class Meta(NsSerializer.Meta):
        fields = ('target',)


class MXRecordSerializer(MxSerializer):
931 932 933
    """Serialize `machines.models.Mx` objects with the data needed to
    generate a MX DNS record.
    """
934
    target = serializers.CharField(source='name', read_only=True)
935 936 937 938 939 940

    class Meta(MxSerializer.Meta):
        fields = ('target', 'priority')


class TXTRecordSerializer(TxtSerializer):
941 942 943
    """Serialize `machines.models.Txt` objects with the data needed to
    generate a TXT DNS record.
    """
erdnaxe's avatar
erdnaxe committed
944

945 946 947 948 949
    class Meta(TxtSerializer.Meta):
        fields = ('field1', 'field2')


class SRVRecordSerializer(SrvSerializer):
950 951 952
    """Serialize `machines.models.Srv` objects with the data needed to
    generate a SRV DNS record.
    """
953 954 955 956 957 958
    target = serializers.CharField(source='target.name', read_only=True)

    class Meta(SrvSerializer.Meta):
        fields = ('service', 'protocole', 'ttl', 'priority', 'weight', 'port', 'target')


959 960 961 962
class SSHFPRecordSerializer(SshFpSerializer):
    """Serialize `machines.models.SshFp` objects with the data needed to
    generate a SSHFP DNS record.
    """
erdnaxe's avatar
erdnaxe committed
963

964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979
    class Meta(SshFpSerializer.Meta):
        fields = ('algo_id', 'hash')


class SSHFPInterfaceSerializer(serializers.ModelSerializer):
    """Serialize `machines.models.Domain` objects with the data needed to
    generate a CNAME DNS record.
    """
    hostname = serializers.CharField(source='domain.name', read_only=True)
    sshfp = SSHFPRecordSerializer(source='machine.sshfp_set', many=True, read_only=True)

    class Meta:
        model = machines.Interface
        fields = ('hostname', 'sshfp')


980
class ARecordSerializer(serializers.ModelSerializer):
981 982 983
    """Serialize `machines.models.Interface` objects with the data needed to
    generate a A DNS record.
    """
984 985 986 987 988 989 990 991 992
    hostname = serializers.CharField(source='domain.name', read_only=True)
    ipv4 = serializers.CharField(source='ipv4.ipv4', read_only=True)

    class Meta:
        model = machines.Interface
        fields = ('hostname', 'ipv4')


class AAAARecordSerializer(serializers.ModelSerializer):
993 994 995
    """Serialize `machines.models.Interface` objects with the data needed to
    generate a AAAA DNS record.
    """
996
    hostname = serializers.CharField(source='domain.name', read_only=True)
997
    ipv6 = Ipv6ListSerializer(many=True, read_only=True)
998 999 1000 1001 1002 1003 1004

    class Meta:
        model = machines.Interface
        fields = ('hostname', 'ipv6')


class CNAMERecordSerializer(serializers.ModelSerializer):
1005 1006 1007
    """Serialize `machines.models.Domain` objects with the data needed to
    generate a CNAME DNS record.
    """
Charlie Jacomme's avatar
Charlie Jacomme committed
1008
    alias = serializers.CharField(source='cname', read_only=True)
1009 1010 1011 1012
    hostname = serializers.CharField(source='name', read_only=True)

    class Meta:
        model = machines.Domain
Charlie Jacomme's avatar
Charlie Jacomme committed
1013
        fields = ('alias', 'hostname')
1014

Gabriel Detraz's avatar
Gabriel Detraz committed
1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025
class DNAMERecordSerializer(serializers.ModelSerializer):
    """Serialize `machines.models.Domain` objects with the data needed to
    generate a DNAME DNS record.
    """
    alias = serializers.CharField(read_only=True)
    zone = serializers.CharField(read_only=True)

    class Meta:
        model = machines.DName
        fields = ('alias', 'zone')

1026

1027
class DNSZonesSerializer(serializers.ModelSerializer):
1028 1029
    """Serialize the data about DNS Zones.
    """
1030 1031 1032
    soa = SOARecordSerializer()
    ns_records = NSRecordSerializer(many=True, source='ns_set')
    originv4 = OriginV4RecordSerializer(source='origin')
1033
    originv6 = serializers.CharField(source='origin_v6')
1034 1035 1036 1037 1038 1039
    mx_records = MXRecordSerializer(many=True, source='mx_set')
    txt_records = TXTRecordSerializer(many=True, source='txt_set')
    srv_records = SRVRecordSerializer(many=True, source='srv_set')
    a_records = ARecordSerializer(many=True, source='get_associated_a_records')
    aaaa_records = AAAARecordSerializer(many=True, source='get_associated_aaaa_records')
    cname_records = CNAMERecordSerializer(many=True, source='get_associated_cname_records')
Gabriel Detraz's avatar
Gabriel Detraz committed
1040
    dname_records = DNAMERecordSerializer(many=True, source='get_associated_dname_records')
1041
    sshfp_records = SSHFPInterfaceSerializer(many=True, source='get_associated_sshfp_records')
1042 1043 1044 1045 1046

    class Meta:
        model = machines.Extension
        fields = ('name', 'soa', 'ns_records', 'originv4', 'originv6',
                  'mx_records', 'txt_records', 'srv_records', 'a_records',
Gabriel Detraz's avatar
Gabriel Detraz committed
1047
                  'aaaa_records', 'cname_records', 'dname_records', 'sshfp_records')
1048 1049 1050 1051 1052 1053 1054
#REMINDER


class ReminderUsersSerializer(UserSerializer):
    """Serialize the data about a mailing member.
    """
    class Meta(UserSerializer.Meta):
1055
        fields = ('get_full_name', 'get_mail')
1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067


class ReminderSerializer(serializers.ModelSerializer):
    """
    Serialize the data about a reminder
    """
    users_to_remind = ReminderUsersSerializer(many=True)

    class Meta:
        model = preferences.Reminder
        fields = ('days','message','users_to_remind')

1068

1069 1070 1071 1072 1073
class DNSReverseZonesSerializer(serializers.ModelSerializer):
    """Serialize the data about DNS Zones.
    """
    soa = SOARecordSerializer(source='extension.soa')
    extension = serializers.CharField(source='extension.name', read_only=True)
1074
    cidrs = serializers.ListField(child=serializers.CharField(), source='ip_set_cidrs_as_str', read_only=True)
1075 1076 1077 1078 1079 1080 1081 1082 1083
    ns_records = NSRecordSerializer(many=True, source='extension.ns_set')
    mx_records = MXRecordSerializer(many=True, source='extension.mx_set')
    txt_records = TXTRecordSerializer(many=True, source='extension.txt_set')
    ptr_records = ARecordSerializer(many=True, source='get_associated_ptr_records')
    ptr_v6_records = AAAARecordSerializer(many=True, source='get_associated_ptr_v6_records')

    class Meta:
        model = machines.IpType
        fields = ('type', 'extension', 'soa', 'ns_records', 'mx_records',
1084
                  'txt_records', 'ptr_records', 'ptr_v6_records', 'cidrs',
1085
                  'prefix_v6', 'prefix_v6_length')
1086

erdnaxe's avatar
erdnaxe committed
1087

1088
# MAILING
1089 1090 1091


class MailingMemberSerializer(UserSerializer):
1092 1093
    """Serialize the data about a mailing member.
    """
erdnaxe's avatar
erdnaxe committed
1094

1095
    class Meta(UserSerializer.Meta):
1096
        fields = ('name', 'pseudo', 'get_mail')
1097

erdnaxe's avatar
erdnaxe committed
1098

1099
class MailingSerializer(ClubSerializer):
1100 1101
    """Serialize the data about a mailing.
    """
1102 1103 1104 1105 1106
    members = MailingMemberSerializer(many=True)
    admins = MailingMemberSerializer(source='administrators', many=True)

    class Meta(ClubSerializer.Meta):
        fields = ('name', 'members', 'admins')