user3564183
user3564183

Reputation: 183

Django Rest Framework 3.0 : IntegrityError Exception Value: (1048, "Column' cannot be null")

I have defined models as below

from django.db import models

# Create your models here.
    class Customer(models.Model):    
        cust_firstname=models.TextField(max_length=50)
        cust_lastname=models.TextField(max_length=50)
        cust_company=models.TextField(max_length=100)
        created_at = models.DateTimeField(auto_now_add=True)
        updated_at = models.DateTimeField(auto_now=True)
        cust_contact_number = models.IntegerField()
        cust_email = models.TextField(max_length=100)
        cust_address=models.TextField(max_length=200,default=None)

        def __unicode__(self):
           return self.cust_firstname

    class Employee(models.Model):
        employee_firstname = models.TextField(max_length=50)
        employee_lastname = models.TextField(max_length=50)
        created_at = models.DateTimeField(auto_now_add=True)
        updated_at = models.DateTimeField(auto_now=True)
        employee_contact_number = models.IntegerField()
        employee_email = models.TextField(max_length=100)
        employee_designation = models.TextField(max_length=50)
        employee_address=models.TextField(max_length=200, default=None)

    def __unicode__(self):
        return self.employee_firstname

    class ProjectDetails(models.Model): 
        customer = models.ForeignKey(Customer)
        employee=models.ForeignKey(Employee)
        project_name = models.TextField(max_length=50)
        project_startdate = models.DateField(auto_now=False, default=None)
        project_status = models.TextField(default="Initial")
        created_at = models.DateTimeField(auto_now_add=True)
        updated_at = models.DateTimeField(auto_now=True)

    def __unicode__(self):
        return self.project_name

and my serializer is as shown below

     from ProjectTemplate.models import Customer, Employee, ProjectDetails
     from rest_framework import serializers

       class CustomerSerializers(serializers.ModelSerializer):
         class Meta:
         model=Customer
         fields =   ('id','cust_firstname','cust_lastname','cust_company','created_at','updated_at','cust_contact_number','cust_email','cust_address')

    read_only_fields = ('created_at', 'updated_at')

       class EmployeeSerializer(serializers.ModelSerializer):
        class Meta:
         model=Employee
          fields =   ('id','employee_firstname','employee_lastname','created_at','updated_at','employee_contact_number','employee_email','employee_designation','employee_address')

    read_only_fields = ('created_at', 'updated_at')

class ProjectDetailsSerializer(serializers.ModelSerializer):
#customer = CustomerSerializers(read_only=True)
#employee = EmployeeSerializer(read_only=True)
    customer = serializers.SlugRelatedField(slug_field='cust_firstname', read_only=True)
    employee = serializers.SlugRelatedField(slug_field='employee_firstname', read_only=True)
class Meta:
        model = ProjectDetails
        fields =       ('id','project_name','project_startdate','created_at','updated_at','project_status','customer','employee')
        read_only_fields = ('created_at', 'updated_at')

and my POST method in the view is

    from django.http import Http404
    from ProjectTemplate.models import ProjectDetails, Customer, Employee
    from ProjectTemplate.serializers import ProjectDetailsSerializer,               CustomerSerializers, EmployeeSerializer
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from rest_framework import status



class ProjectViewSet(viewsets.ModelViewSet):
    queryset = ProjectDetails.objects.all()
    serializer_class = ProjectDetailsSerializer


def perform_create(self, serializer):
    custid = self.request.data.get("customer_id")
    empid = self.request.data.get("employee_id")
    serializer.save(
        customer=Customer.objects.get(pk=custid),
        employee=Employee.objects.get(pk=empid))

def perform_update(self, serializer):       
    custid = self.request.data.get("customer_id")
    empid = self.request.data.get("employee_id")
    serializer.save(
        customer=Customer.objects.get(pk=custid),
        employee=Employee.objects.get(pk=empid))

def perform_destroy(self, instance):
        instance = self.get_object()
        instance.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

When i try to post a request i get an integrity error. the code does not save the object since it is not getting the customer_id foreign key value. Please find the screen shot attached. can some sone help me to know whats wrong in the serializer method.enter image description here

Upvotes: 0

Views: 763

Answers (1)

AKS
AKS

Reputation: 19831

You are getting this error because when you are saving the serializer the customer and employee are not set on the instance. Setting these values on the serializer itself won't have any effect at all. You have to pass these additional values in the save method of the serializer.

Additionally, I would suggest that you override the perform_create method and not the post method:

def perform_create(self, serializer):
    custid = self.request.data.get("customer_id")
    empid = self.request.data.get("employee_id")
    serializer.save(
        customer=Customer.objects.get(pk=custid),
        employee=Employee.objects.get(pk=empid)
    )

This is straight from the documentation:

The following methods are provided by the mixin classes, and provide easy overriding of the object save or deletion behavior.

  • perform_create(self, serializer) - Called by CreateModelMixin when saving a new object instance.

UPDATE on using ModelViewSet:

You don't need to use APIView but you could use ModelViewSet for different operations e.g. list, retrieve, create etc.

class ProjectViewSet(viewsets.ModelViewSet):

    queryset = ProjectDetails.objects.all()
    serializer_class = ProjectDetailsSerializer

    # now you can add your perform_create here
    def perform_create(self, serializer):
        custid = self.request.data.get("customer_id")
        empid = self.request.data.get("employee_id")
        serializer.save(
            customer=Customer.objects.get(pk=custid),
            employee=Employee.objects.get(pk=empid)
        )

Upvotes: 1

Related Questions