Issue:
When uploading data with an image, the following issue occurs if some PrimaryKeyRelatedField is missing or the field ID is not valid. If I don’t upload any image file, then expected output field validation issues arise.
Encountered Issue:
If I send some missing or invalid data with image files, the following issue occurs. However, the expected result was a validation issue.
Validation Issue [expected output]:
The API shows the following output if I don’t send any image file, which is the expected output.
{
"status": false,
"errors": {
"service_cost_details": [
"This field is required."
],
"photo": [
"No file was submitted."
],
"citizenship_front": [
"No file was submitted."
],
"citizenship_back": [
"No file was submitted."
],
"province": [
"Invalid pk "75242546" - object does not exist."
]
},
"results": {
"house_number": "420",
"old_membership_number": "",
"first_name": "test",
"middle_name": "test",
"last_name": "456",
"email": "[email protected]",
"phone_number": "9895655644",
"address": "madhyabindu",
"date_of_birth": "2024-08-15",
"gender": "Male",
"pan_number": "420",
"family_member_count": "4",
"citizenship_number": "56551",
"citizenship_issue_district": "1",
"province": "75242546",
"district": "2",
"municipality": "3",
"ward": "4",
"tol": null
}
}
My model Looks like:
class ConsumerDetails(CreatorModifierInfo):
gender_select = (("Male", "Male"), ("Female", "Female"), ("Other", "Other"))
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True, db_index=True)
office = models.ForeignKey(Office, null=True, blank=True, on_delete=models.SET_NULL)
service_cost_details = models.ForeignKey(ServiceCostDetails, null=True, on_delete=models.SET_NULL)
house_number = models.CharField(max_length=1000, null=True, blank=True)
old_membership_number = models.CharField(max_length=1000, null=True, blank=True)
membership_number = models.CharField(max_length=1000, unique=True, null=True, blank=True)
first_name = models.CharField( max_length=150, null=True)
middle_name = models.CharField(max_length=150, null=True, blank=True)
last_name = models.CharField(max_length=150, null=True)
email = models.EmailField(null=True, blank=True)
phone_number = models.CharField(max_length=20, null=True, blank=True)
photo = models.ImageField(null=True, blank=True, upload_to='consumer/image/%Y/%m/%d/')
address = models.CharField(max_length=1000, null=True, blank=True)
date_of_birth = models.DateField(null=True, blank=True)
gender = models.CharField(choices=gender_select, max_length=200, null=True, blank=True)
pan_number = models.CharField(max_length=1000, null=True, blank=True)
family_member_count = models.PositiveIntegerField(null=True, blank=True, default=0)
citizenship_number = models.CharField(max_length=1000, null=True, blank=True)
citizenship_issue_district = models.ForeignKey(District, related_name='citizenship_issue_district', null=True, blank=True, on_delete=models.SET_NULL)
citizenship_front = models.ImageField(null=True, blank=True, upload_to='consumer/image/%Y/%m/%d/')
citizenship_back = models.ImageField(null=True, blank=True, upload_to='consumer/image/%Y/%m/%d/')
province = models.ForeignKey(Province, null=True, on_delete=models.SET_NULL)
district = models.ForeignKey(District, null=True, on_delete=models.SET_NULL)
municipality = models.ForeignKey(Municipality, null=True, on_delete=models.SET_NULL)
ward = models.ForeignKey(Ward, null=True, on_delete=models.SET_NULL)
tol = models.ForeignKey(Tol, null=True, on_delete=models.SET_NULL)
business_details = models.ManyToManyField(BusinessDetails, blank=True)
rental_details = models.ManyToManyField(RentalDetails, blank=True)
account_balance = models.FloatField(null=True, blank=True, default=0)
active_status = models.BooleanField(default=True, null=True, blank=True)
status = models.BooleanField(default=True, null=True, blank=True)
def __str__(self):
return self.membership_number if self.membership_number else f"{self.id}"
Serializer looks like:
class ConsumerDetailsSerializer(serializers.ModelSerializer):
service_cost_details = serializers.PrimaryKeyRelatedField(queryset=ServiceCostDetails.objects.all(), required=True, allow_empty=True, allow_null=True)
first_name = serializers.CharField(required=True)
last_name = serializers.CharField(required=True)
date_of_birth = serializers.DateField(required=True)
gender = serializers.CharField(required=True)
family_member_count = serializers.IntegerField(required=True)
citizenship_number = serializers.CharField(required=True)
province = serializers.PrimaryKeyRelatedField(queryset=Province.objects.all(), required=True, allow_null=True, allow_empty=True)
district = serializers.PrimaryKeyRelatedField(queryset=District.objects.all(), required=True, allow_empty=True, allow_null=True)
municipality = serializers.PrimaryKeyRelatedField(queryset=Municipality.objects.all(), required=True, allow_empty=True, allow_null=True)
ward = serializers.PrimaryKeyRelatedField(queryset=Ward.objects.all(), required=True, allow_empty=True, allow_null=True)
tol = serializers.PrimaryKeyRelatedField(queryset=Tol.objects.all(), required=True, allow_empty=True, allow_null=True)
citizenship_front = serializers.ImageField()
citizenship_back = serializers.ImageField()
photo = serializers.ImageField()
Class Meta:
model = ConsumerDetails
fields = ['id', 'service_cost_details', 'house_number', 'old_membership_number',
'first_name', 'middle_name', 'last_name', 'email', 'phone_number', 'photo', 'address',
'date_of_birth', 'gender', 'pan_number', 'family_member_count', 'citizenship_number',
'citizenship_issue_district', 'citizenship_front', 'citizenship_back', 'province', 'district',
'municipality', 'ward', 'tol']
View looks like:
class ConsumerDetailsView(viewsets.ViewSet, CustomPagination):
permission_classes = [IsAuthenticated, HasGroupPermission]
def create(self, request):
"""
Create a Consumer Detail.
"""
serializer = ConsumerDetailsSerializer(data=request.data)
api_status = False
if serializer.is_valid():
serializer.save(creator=self.request.user, office=self.request.user.office)
api_status = True
return Response(
{
"status": api_status,
"errors": serializer.errors,
"results": serializer.data
}, status=status.HTTP_200_OK if api_status else status.HTTP_400_BAD_REQUEST
)