简体   繁体   中英

Embeded serializers in DRF for mongo and django

I am trying to create a non model embeded serializer in Django Rest Framework. I'm stuck here. Need you help. Thanks in advance.

class IPNetwork(serializers.ListSerializer):
    network_netmask = serializers.IPAddressField(required=False)
    network_gateway = serializers.IPAddressField(required=False)
    network_mac = serializers.CharField(required=False)
    network_dns = serializers.ListField(required=False)
    network_ip = serializers.IPAddressField(required=False)

class RouterInfoSerializer(serializers.Serializer):
    router_name = serializers.CharField(required=False)
    router_ip_networks = IPNetwork(many=True)
    router_devices = serializers.ListField(required=False)

I'm using DRF serializers to authenticate API data but storing it in mongoDB. So i can't use Model Serializer. So I wanted to know if there is any way to write nested serializers without using the Model serializers. Nested serializers mentioned here

My sample input data will be in this format

{
  "name": "Test Router",
  "ip_networks":[
    {
      "ip": "192.168.1.1",
      "netmask": "255.255.255.0",
      "gateway": "192.168.1.1",
      "mac": "EA:8C:0C:1F:BC:DC",
      "dns": ["8.8.8.8", "8.8.4.4"]
    }
  ],
  "router_devices": ["List of clients connected"]
}

On this data input, I want to validate the ip data also in the serializer and then call the save function.

I want something similar to embedded document mongoengine

The biggest issue here is that you have IPNetwork(many=True) and set IPNetwork as ListSerializer .

One should know that this is redondant as many=True creates a ListSerializer behind the scene. Also note that ListSerializer are intended to work with a child serializer which is different from your implementation.

Therefore, you should simply make IPNetwork inherit from serializers.Serializer and you should be good to go.

Non model serializers works - mostly - the same as ModelSerializers except that they return python dictionaries unless the create/update are overridden. Note that in your case with nested serializers, those two methods should be overridden anyway.

Ok. So this is how i did and it works great.

class IPNetwork(serializers.Serializer):
  network_netmask = serializers.IPAddressField(required=True)
  network_gateway = serializers.IPAddressField(required=True)
  network_mac = serializers.CharField(required=True)
  network_dns = serializers.ListField(required=True)
  network_ip = serializers.IPAddressField(required=True)

class RouterInfoSerializer(serializers.Serializer):
  router_name = serializers.CharField(required=True)
  router_ip_networks = serializers.ListField(required=True)
  router_devices = serializers.ListField(required=False)

  def validate_router_ip_networks(self, value):
    if not IPNetwork(data=value, many=True).is_valid():
      raise serializers.ValidationError("Router IP network data is invalid")
    return value

Let me know if any issues with this code or anyone has any queries.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM