Home > other >  DRF DateField - error when saving form: Date has wrong format. Use one of these formats instead: YYY
DRF DateField - error when saving form: Date has wrong format. Use one of these formats instead: YYY

Time:09-17

I'm POSTing a form to my Django Rest Framework backend.

There is a DateField I am using which is optional depending on the form type the user is looking at.

When the user can see the DateField and select the date, it submits appropriately and there are no issues.

When the DateField is hidden, I am getting a formatting error when I submit the form (but shouldn't)

The form renders the elements appropriately via HTML:

When the date is VISIBLE:

<div class="mt-2 text-center">
    <input type="hidden" name="summative" value="127" id="id_summative">
    <input type="hidden" name="evaluation_type" value="31" id="id_evaluation_type">
    <div id="id_evaluation_levelFormGroup" class="form-group">
        <label class="form-label" for="id_evaluation_level">Evaluation level</label>
        <select name="evaluation_level" class="form-control" required="" id="id_evaluation_level">
            <option value="" selected="">---------</option>
            <option value="41">Formal</option>
            <option value="42">Informal</option>
        </select>
    </div>
    <div id="id_evaluation_dateFormGroup" class="form-group">
        <label class="form-label" for="id_evaluation_date">Evaluation date</label>
        <input type="date" name="evaluation_date" value="2021-09-08" class="form-control" id="id_evaluation_date">
    </div>
</div>

When HIDDEN:

<div class="mt-2 text-center">
    <input type="hidden" name="summative" value="127" id="id_summative">
    <input type="hidden" name="evaluation_type" value="33" id="id_evaluation_type">
    <input type="hidden" name="evaluation_level" value="43" id="id_evaluation_level">
    <input type="hidden" name="evaluation_date" id="id_evaluation_date">
</div>

The evaluation_date is not a required field, the model attribute looks like this:

    evaluation_date = models.DateField(
        auto_now=False, auto_now_add=False, null=True, blank=True
    )

My Serializer looks like this (includes the validation method for the date):

class EvaluationSerializer(serializers.ModelSerializer):
    def validate_evaluation_date(self, attrs):
        # Get the date string
        date_string = self.context["request"].data["evaluation_date"]
        # Get the type
        evaluation_type_id = self.context["request"].data["evaluation_type"]
        evaluation_type = EvaluationType.objects.get(id=evaluation_type_id)
        # If we have an Observation, blanks should not be allowed
        if evaluation_type.name == "Observation" and attrs == None:
            raise serializers.ValidationError("This field is required.")
        if evaluation_type.name == "Observation" and attrs == "":
            raise serializers.ValidationError("This field is required.")
        # Parse the string into a date object
        date = datetime.strptime(date_string, "%Y-%m-%d").date()
        return date

    absolute_url = serializers.SerializerMethodField()
    created_by = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )
    updated_by = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )
    evidences = serializers.SerializerMethodField()
    requestor_can_add = serializers.SerializerMethodField()
    subdomains = serializers.SerializerMethodField()
    evaluation_date = serializers.DateField()

    class Meta:
        model = Evaluation
        fields = [
            "url",
            "absolute_url",
            "id",
            "summative",
            "employee_locked",
            "admin_locked",
            "admin_locked_by_id",
            "published",
            "evidences",
            "subdomains",
            "requestor_can_add",
            "evaluation_type",
            "evaluation_level",
            "evaluation_date",
            "created_by",
            "updated_by",
        ]

In my settings I setup my input formats like this:

REST_FRAMEWORK = {
    "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
    "DATETIME_FORMAT": "%m/%d/%Y - %I:%M:%S %p",
    "DATE_INPUT_FORMATS": ["%Y-%m-%d"],
    "DEFAULT_AUTHENTICATION_CLASSES": [
        # Enabling this it will require Django Session (Including CSRF)
        "rest_framework.authentication.SessionAuthentication"
    ],
    "DEFAULT_PERMISSION_CLASSES": [
        # Globally only allow IsAuthenticated users access to API Endpoints
        "rest_framework.permissions.IsAuthenticated"
    ],
}

The issue is this -- when I submit the form (when the inputs are hidden and the evaluation_date should be blank, it gives the following error:

Date has wrong format. Use one of these formats instead: YYYY-MM-DD.

But the value should be blank (as you can see from the HTML above)

CodePudding user response:

Problem is you're declaring evaluation_date in your serializer:

evaluation_date = serializers.DateField()

Because of this the field is required. Just delete that from the serializer and it should work.

  • Related