[Answered ]-Validation of the serial number against the mask in Django rest

1👍

First of all, there is one clash in your Mask, meaning there will be more than one version for the same type since:

A is a capital letter of the Latin alphabet;
...
X is a capital letter of the Latin alphabet or a number from 0 to 9;

More precisely 0QWER9@123 corresponds to NAAAAXZXXX but also to NAAAANZNNN. Unless you impose some condition, which I will do in my example in order to obtain the desired result (Only the first numeric element gets 'N' the others will get 'X').

Now, to answer your question. I believe an elegant way to implement this would be to write a custom validator that you can place in a separate file:

validators.py

def validate_sn_mask(value):
    mask = ""
    special_list = ["-", "_", "@"]
    first_number = True

    for character in value:
        if character.isnumeric():
            if first_number:
                mask += "N"
                first_number = False
            else:
                mask += "X"
        elif character.isalpha():
            if character.isupper():
                mask += "A"
            else:
                mask += "a"
        elif character in special_list:
            mask += "Z"
        else:
            # Although you already have a regex in your Model
            raise ValidationError({"msg": "Invalid Mask"})

    qs = Type_Of_Equipment.objects.filter(sn_mask=mask)

    if not qs:
        raise ValidationError({"msg": "Mask has no correspondent type"})

    return qs[0]

serializers.py

class EquipmentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Equipment
        fields = ['code', 'sn_number','type_of_equipment']
        extra_kwargs = {
            'type_of_equipment': {'required': False}
        }
    
    def validate(self, attrs):
        equipment_type_instance = validate_sn_mask(attrs['sn_number'])
        attrs['type_of_equipment'] = equipment_type_instance
        return super().validate(attrs)

views.py

class GetOrCreateEquip(APIView):
    def get(self, request):
        ...

    def post(self, request):
        serializer = EquipmentSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)
👤Niko

Leave a comment