布尔字段始终保存False Django

时间:2019-11-13 08:17:19

标签: python django django-models django-rest-framework

我使用的是Django Rest Framework,当有效载荷来自发布请求时,我有一个company_status的布尔字段,该字段为true,但是当用户保存它为False时,我无法得到问题所在:

views.py

class CreateUser(APIView):

    def get(self,request):
        return Response([UserSerializer(dat).data for dat in User.objects.all()])

    def post(self,request):
        payload=request.data
        serializer = UserSerializer(data=payload) 
        print(payload)  # here it shows company_status True
        if serializer.is_valid():
            instance = serializer.save()
            instance.set_password(instance.password)
            instance.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

serializers.py

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = ['id','username','user_image','designation','company_status','age','gender']

    def create(self, validated_data):
        user = User.objects.create(**validated_data)
        return user

    def update(self, instance, validated_data):
        for k, v in validated_data.items():
            setattr(instance, k, v)
            instance.save()
        return instance

models.py

class User(AbstractBaseUser,PermissionsMixin):

    # is_admin=models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    first_name = models.CharField(max_length=30, blank=True)
    last_name = models.CharField(max_length=30, blank=True)
    date_joined = models.DateTimeField(null=True, blank=True)
    user_image=models.ImageField(upload_to=user_main_image_directory_path,null=True,blank=True)
    username = models.CharField(

        max_length=150,
        unique=True,
        null=True,

    )
    is_active = models.BooleanField(default=True)
    phonenumber=models.CharField(max_length=13,default="null")
    faceid=HashidField
    is_booker=models.BooleanField(default=False)
    designation=models.CharField(max_length=30,null=True)
    company_status=models.BooleanField(null=True,blank=True)  # this is the field
    object = UserManager()
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = []
    age=models.IntegerField(null=True)
    gender=models.CharField(max_length=10,null=True,blank=True)

回复

Response:

        "id": 1,
        "username": "nabeel",
        "user_image": "/media/1/opencv_frame_0.jpg",
        "designation": "bscs",
        "company_status": false,
        "age": 23,
        "gender": "male"
    }

请求有效载荷

Request payload:
payload={
age:25
company_statu:true
designation:bscs
gender:male
password:manofsteel#2
username:xyz
}

无法弄清为什么总是在company_status中保存False,我已经打印了有效载荷来自发布请求,并且显示True,但是当序列化程序保存时,它显示false

2 个答案:

答案 0 :(得分:2)

首先,建议您修改序列化程序,以检查序列化程序是否收到company_status。使其更改如下:

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = ['id','username','user_image','designation','company_status','age','gender']
        extra_kwargs = dict(company_status=dict(required=True, allow_null=False))

    def create(self, validated_data):
        user = User.objects.create(**validated_data)
        return user

    def update(self, instance, validated_data):
        for k, v in validated_data.items():
            setattr(instance, k, v)
            instance.save()
        return instance

如果序列化程序引发ValidationError,则很可能是您的序列化程序无法理解request.data,因此无法正确地反序列化。在这里,您必须查看您的React代码是否以请求标头中的content-type:application/json发送。

第二,如果不是这种情况,请检查模型迁移,也许一开始您使用default=False拥有布尔字段,然后进行了更改,但是却忘记了进行更改。

第三,即使无济于事,那么如果您之前对数据库设置进行了一些更改,那么问题可能会在数据库配置的最低级别更深层出现。

即使不是这种情况,我也很抱歉告诉您您搞砸了项目设置。

答案 1 :(得分:0)

如果您使用new FormData()来构建有效负载,那么序列化程序将正确处理任何布尔字段,但是如果您使用的是表并且在所有数据都存在时提交行(POST)或提交进行更改(PUT)后,您将没有<form id="form_name"></form>标签围绕要提交的数据,因此无法进行new FormData(form_name)创建有效负载。以下是在后一种情况下创建有效负载的工作方式(请注意,复选框值设置为onoff,并且设置方式与您期望的相反):

function submitRow($tr, deleteRow) {
    // Build data for submission but return if any item does not have data
    var data = {};
    ready = true;
    if (!deleteRow) {
        // Determine whether all data in a row is present
        $tr.find('input, select').each(function(idx, el){
            if ($(el).val() == '' && !($(el).attr('type') == 'checkbox')) {
                ready = false;
                return false;
            }
            // The state of the checkbox is still opposite at this point
            if ($(el).attr('type') == 'checkbox' && el.checked) {
                data[$(el).attr('name')] = 'on';
            } else if ($(el).attr('type') == 'checkbox' && !el.checked) {
                data[$(el).attr('name')] = 'off';
            } else {
                data[$(el).attr('name')] = $(el).val();
            }
        })
    }
    data['csrfmiddlewaretoken'] = $('input[name="csrfmiddlewaretoken"]').val();

    if (ready) {
        data = JSON.stringify(data);
        // Set up submission type
        if (deleteRow) {
            var method = 'DELETE'
            var url = '/child/delete/' + $tr.data('child-reg-id') + '/'
        }
        else if ($tr.data('child-reg-id') == '') {
            var method = 'POST'
            var url = '/child/add/'
        } else {
            var method = 'PUT'
            var url = '/child/update/' + $tr.data('child-reg-id') + '/'
        }
        
        fetch(url, {
            method: method,
            headers: {
                "X-CSRFToken": $('input[name="csrfmiddlewaretoken"]').first().val(),
                "Accept": "application/json",
                "Content-Type": "application/json"
            },
            credentials: 'include',
            body: data
        })
        .then(function(result) {
            return result.json();
        })
        .then(function(data) {
            // Final logic to process the returned data
        })
    }
}

确保像这样设置tr的提交:

$('table tbody').on("change", "tr input, tr select", function(e) {
    submitRow($(e.target).closest('tr'), false);
})
// Handle deleting a row in which a Font Awesome "remove" icon is present in the row and is clicked to delete the row
$('table tbody').on("click", ".fa-remove", function(e) {
    submitRow($(e.target).closest('tr'), true);
})