I have the following codes:
models.py
class Device(models.Model):
hostname = models.CharField(max_length=50, unique = True)
ipaddr = models.GenericIPAddressField(protocol='ipv4', unique=True, verbose_name='mangement IP') ##Use for mgt_id_addr
date_added = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.hostname
class DeviceDetail(models.Model):
SUBNET_CHOICES = (
('16','16'),
('17', '17'),
('18','18'),
('19','19'),
('20','20'),
('21', '21'),
('22', '22'),
('23', '23'),
('24', '24'),
('25', '25'),
('26', '26'),
('27', '27'),
('28', '28'),
('29', '29'),
('30', '30'),
)
DEV_MODS =(
('Catalyst 9606R', 'Catalyst 9606R'),
('C9300L-48T-4X', 'C9300L-48T-4X')
)
mgt_interface = models.CharField(max_length=50)
subnetmask = models.CharField(max_length=2, choices = SUBNET_CHOICES)
ssh_id = models.CharField(max_length=50)
ssh_pwd = models.CharField(max_length=50)
enable_secret = models.CharField(max_length=50)
dev_mod=models.CharField(max_length=50, choices = DEV_MODS) ##device_model replacement
DD2DKEY = models.ForeignKey(Device, on_delete=models.CASCADE) ##The key to link up the tables
def __str__(self):
return self.hostname
serializers.py
from rest_framework import serializers
from .models import Device, DeviceDetail
class DeviceSerializers(serializers.ModelSerializer):
class Meta:
model=Device
fields = '__all__'
class DeviceDetailSerializers(serializers.ModelSerializer):
class Meta:
model = DeviceDetail
fields = ['mgt_interface', 'subnetmask', 'ssh_id', 'ssh_pwd', 'enable_secret', 'dev_mod']
views.py
@api_view(['POST'])
def create_device(request):
device = Device()
devicedetail = DeviceDetail()
deviceserializer = DeviceSerializers(device, data = request.data)
devdserializer = DeviceDetailSerializers(devicedetail, data = request.data)
if deviceserializer.is_valid() and devdserializer.is_valid():
device_instance = deviceserializer.save()
devdserializer.save(DD2DKEY=device_instance)
results = {
"device":deviceserializer.data,
"device_details" : devdserializer.data,
}
return Response(results, status=status.HTTP_201_CREATED)
else:
errors = {
"device":deviceserializer.errors,
"device_details" : devdserializer.errors,
}
return Response(errors, status=status.HTTP_400_BAD_REQUEST)
I am facing the following error: AssertionError: You must call .is_valid()
before accessing .errors
.
How do i correct this to fixed the issue in case my codes enter the else condition so it will show the errors of the serializers? Because no matter what I still have to return a response if it failes
CodePudding user response:
If deviceserializer.is_valid()
fails, then the if
condition will shortcircuit and thus not call devdserializer.is_valid()
. You thus should ensure that it calls devdserializer.is_valid()
as well:
if deviceserializer.is_valid() and devdserializer.is_valid():
device_instance = deviceserializer.save()
devdserializer.save(DD2DKEY=device_instance)
results = {
"device":deviceserializer.data,
"device_details" : devdserializer.data,
}
return Response(results, status=status.HTTP_201_CREATED)
else:
# ↓ ensure that is_valid() is called
devdserializer.is_valid()
errors = {
"device":deviceserializer.errors,
"device_details" : devdserializer.errors,
}
return Response(errors, status=status.HTTP_400_BAD_REQUEST)