Search code examples
pythondjangodjango-rest-frameworkdjango-serializerdjango-jsonform

Django REST API view post serializer.save sets one parameter 'null'


In Django, I have the following model:

class business(models.Model):
    business_category = models.ForeignKey(businessCategory, related_name='businesss', on_delete=models.CASCADE)
    partner1 = models.CharField(max_length=255)  #, blank=True, null=True)
    partner1_is_creator = models.BooleanField(default=True)
    partner2 = models.CharField(max_length=255)
    creator = models.ForeignKey(User, related_name='businesss', on_delete=models.CASCADE, null=True)
    name = models.CharField(max_length=255)
    setting = models.CharField(max_length=255)
    estimated_budget = models.FloatField()
    location = models.CharField(max_length=255)
    date_created = models.DateTimeField(auto_now_add=True)
    business_start_date = models.DateTimeField(null=True, editable=True, default=django.utils.timezone.now)
    business_end_date = models.DateTimeField(null=True, editable=True, default=django.utils.timezone.now)

This is the related serializer:

class BusinessCreator(serializers.ModelSerializer):
    class Meta:
        model = business
        fields = ['business_category', 'name', 'partner1', 'partner2', 'partner1_is_creator', 'business_start_date',
                  'location', 'setting', 'estimated_budget']

and this is the view:

class BusinessList(APIView):
    @method_decorator(login_required, name='dispatch')
    def get(self, request):
        created_user = request.user
        businesss = Business.objects.filter(creator=created_user)
        serializer = BusinessSummary(businesss, many=True)
        return Response(serializer.data)

    @method_decorator(login_required, name='dispatch')
    def post(self, request):
        new_business = request.data.get('business')
        serialized_business = BusinessCreator(data=new_business)
        if serialized_business.is_valid(raise_exception=True):
            print(serialized_business.validated_data)
            serialized_business.save()
            return Response(serialized_business.data, status=201)
        return Response(serialized_business.errors, status=400)

The get() method works well.

But when I send the following JSON message via a post message,

{
"business":{
    "business_category": 3,
    "name": "business1",
    "partner1": "john",
    "partner2": "smith",
    "partner1_is_owner": true,
    "business_start_date": "2024-09-18T08:03:00Z",
    "location": "CA",
    "setting": "club",
    "estimated_budget": 121.0
}
}

serialized_business.save() sets only partner1 as null.

{
"business":{
    "business_category": 3,
    "name": "business1",
    "partner1": null,
    "partner2": "smith",
    "partner1_is_owner": true,
    "business_start_date": "2024-09-18T08:03:00Z",
    "location": "CA",
    "setting": "club",
    "estimated_budget": 121.0
}
}

As a result, this throws an error.

However, the serialized data is properly validated: The output of the print statement in the view function:

{'business_category': <BusinessCategory: food>, 'name': 'business1', 'partner1': 'john', 'partner2': 'smith', 'partner1_is_creator': True, 'business_start_date': datetime.datetime(20
24, 9, 18, 8, 3, tzinfo=zoneinfo.ZoneInfo(key='UTC')), 'location': 'CA', 'setting': 'club', 'estimated_budget': 121.0}

The error message:

IntegrityError at /business/businessviewall/
NOT NULL constraint failed: business_business.partner1

Can someone please tell me what's wrong here?


Solution

  • I tried your code, It works fine in my case. can you check your data from request.data.get("business").

    Few Suggestion:

    • Try naming your model in CamelCase
    • remove the null=True from creator
    • business_start_date = models.DateTimeField(null=True, editable=True, default=django.utils.timezone.now) DateTimeField is editable by default. You're also setting default value and allowing null. might want to use one of those
    • rather then sending {"business" {}} might want to change {data here} and access with request.data in your view.