Choices field has a bug

I have this model:

from django.db import models

class TestField(models.Model):
    M = 'Male'
    F = 'Female'
    O = 'Other'
    GENDER = [ 
        (M, 'Male'),
        (F, 'Female'),
        (O, 'Other'),
    ]
    field = models.CharField(max_length=50, choices=GENDER)

    class Meta:
        db_table = 'test_fields'

    def __str__(self):
        return self.field

and I have this view:


from rest_framework.views import APIView
from rest_framework.response import Response
from testback.models import TestField


class TestBack(APIView):
    def post(self, request):
        gender = request.data.get('gender')
        if TestField.objects.create(field=gender):
            return Response("Success")
        else:
            return Response("Failure")

the form on the front end sends the data to the back and the data I send is FormData() that looks like this:

HTML
<form action="" method="post">
	<fieldset>
		<label for="editGender">Gender</label>
		<select id="editGender" v-model="gender.name">
			<option selected disabled value="">Select</option>
			<option>Female</option>
			<option>Male</option>
			<option>Other</option>
		</select>
	</fieldset>
	<button type="button" @click="sendData">Send</button>
</form>

JAVASCRIPT
import { ref } from "vue";

import { store } from "@/store";

import axios from "axios";

const gender = ref({

name:"",

});

function sendData() {

var formData = new FormData();

formData.append("gender", gender.value.name);

axios.post("/api/v1/test/", formData).then((response) => {

store.messages.push(response);

});

}

When I click the button I get to save the model in the database and if I choose any option from the list that option is saved in the database correctly

BUT if I manually edit the form using dev tools and i change the options to anything even Javascript tags then the model gets created but the field is empty.

Based on the model should the model not be prevented from being created if the options is not one of the choices? Doesn’t this pose a security risk if someone can just change the options in dev tools and save the field to the database? What is the point then of having options if I can just have a normal charfield and do my own validation since there is no validation on the field and choices really serve no purpose?

Validation on the front end can be manipulated so validation on the back end is vital but this seems to not work at all.

You need to properly use a Django form if you want full back-end validation.

See Working with forms.

If you don’t use a Django form, then it is up to you to perform all validation on data being submitted.

Ok thanks I will do the reading.

Can I ask a dumb question pls? Data I send to the back end is JSON formatted correct? If I use DRF and there isn’t the functionality I require for dealing with the data and I want to build a custom view do I have to use forms or must I use serializers to first serialize the data.

Like for example I send data to the back end as formdata, which to me looks like JSON. Do I have to first serialize that data or can I just extract the values (request.data.get) and use that to create a model instance?

Yes, I had missed that you’re using DRF here - this first part addresses typical non-drf usage.

You have a choice when data is being submitted by the browser. The browser can send the data either as JSON or as html form data.

When html form data is submitted, Django converts that to a “dict-like” object, making it available as request.POST.

Or, if the browser has submitted JSON, you can convert that to a dict yourself by accessing request.body.

Either way, you can create the instance of a form from the resultant dictionary.

Now, having said all that, there are other ways to handle this as well.

You don’t need to go through this process for non-form submitted data. You could accept the data through a serializer and then validate the Model directly.

The bottom line is that you can do this either way - whichever you find works best for you.

Thank you Ken appreciate the advice