Hi Ryan,

It is basically a serializer validation error stating that "IP already 
exists" so there is no stack trace. I need to somehow disable unique key 
validation check for IPs when being used as a nested serializer in IPGroups.

On Friday, 17 August 2018 11:31:26 UTC-7, Ryan Kilby wrote:
>
> Hi Arjun,
>
> It would be helpful to see the actual stack trace associated with the 
> error. 
>
> On Thursday, August 16, 2018 at 12:02:02 PM UTC-7, Arjun Nambiar wrote:
>>
>> My models.py
>>
>> from django.db import models
>> from netfields import InetAddressField, CidrAddressField, NetManager
>>
>> class IP(models.Model):
>>     """
>>         Stores IP Objects
>>     """
>>     # name is the reverse lookup of an IP if it exists else it is IP_<value>
>>     name = models.CharField(max_length=50, unique=True)
>>     value = InetAddressField(unique=True)
>>
>>     objects = NetManager()
>>
>>     def __unicode__(self):
>>         return f'{self.name}'
>>
>>
>> class CIDR(models.Model):
>>     """
>>         Stores CIDR Objects
>>     """
>>     # name of a subnet is NETWORK_<value>
>>     name = models.CharField(max_length=50, unique=True)
>>     value = CidrAddressField(unique=True)
>>
>>     objects = NetManager()
>>
>>     def __unicode__(self):
>>         return f'{self.name}'
>>
>>
>> class IPGroup(models.Model):
>>     """
>>         Stores IP Groups
>>     """
>>     name = models.CharField(max_length=50, unique=True)
>>     ips = models.ManyToManyField(IP, through=IPGroupToIP)
>>     cidrs = models.ManyToManyField(CIDR, through=IPGroupToCIDR)
>>
>>     def __unicode__(self):
>>         return f'{self.name}'
>>
>>
>> My serializers.py
>>
>> class IPSerializer(serializers.ModelSerializer):
>>     class Meta:
>>         model = IP
>>         fields = ['id', 'name', 'value']
>>
>>
>> class CIDRSerializer(serializers.ModelSerializer):
>>     class Meta:
>>         model = CIDR
>>         fields = ['id', 'name', 'value']
>>
>>
>> class IPGroupSerializer(serializers.ModelSerializer):
>>     """
>>         This Serializer is responsible for parsing IPGroup POST Request.
>>         It validates the JSON Body and throws error if any of the fields 
>> does not meet requirements.
>>     """
>>     ips = IPSerializer(many=True)
>>     cidrs = CIDRSerializer(many=True)
>>
>>     class Meta:
>>         model = IPGroup
>>         depth = 1
>>         fields = '__all__'
>>
>>     def validate(self, data):
>>         mandatory_list = ['ips', 'cidrs']
>>         if not any(data[item] for item in mandatory_list):
>>             raise serializers.ValidationError("Atleast one of the fields(IP, 
>> Subnets) should be present")
>>
>>         if ' ' in data['name']:
>>             raise serializers.ValidationError("IPGroups cannot have spaces 
>> in their names")
>>
>>         return data
>>
>>     @transaction.atomic()
>>     def create(self, validated_data):
>>         # Pop out ips, subnet since these are M2M and have to be created 
>> separately
>>         ips_data = validated_data.pop('ips', None)
>>         cidrs_data = validated_data.pop('cidrs', None)
>>
>>         # First create an IPGroup with the required name
>>         ip_group = IPGroup.objects.create(name=validated_data['name'])
>>
>>         # Now create the M2M relationships
>>         if ips_data:
>>             for ip in ips_data:
>>                 # Get the ip object id if already created or create it on 
>> the fly and save it
>>                 ip_obj, created = IP.objects.get_or_create(name=ip['name'], 
>> value=ip['value'])
>>                 IPGroupToIP.objects.create(ip_group_id=ip_group.id, 
>> ip_id=ip_obj.id)
>>
>>         if cidrs_data:
>>             for cidr in cidrs_data:
>>                 # Get the subnet object id if already created or create it 
>> on the fly and save it
>>                 cidr_obj, created = 
>> CIDR.objects.get_or_create(name=f"NETWORK_{cidr['name']}", 
>> value=cidr['value'])
>>                 IPGroupToCIDR.objects.create(ip_group_id=ip_group.id, 
>> cidr_id=cidr_obj.id)
>>
>>         return ip_group
>>
>>
>>
>> My views.py
>>
>> class IPGroupCreateView(generics.CreateAPIView):
>>     queryset = IPGroup.objects.get_queryset()
>>     serializer_class = IPGroupSerializer
>>
>>
>> This however keeps giving me a validation error saying that IP or CIDR 
>> already exists. However, I am using the get_or_create to create IPs and 
>> CIDRs and hence should not be getting this error. I am assuming that this 
>> happening 
>> because of the nested model serializer's unique field validation kicking 
>> in. How would I disable the unique key validation for IPs and CIDRs only 
>> when i am creating an IPGroup ?
>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-rest-framework+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to