Django REST Framework NOT NULL约束失败:afritechjobsapi_postajob. job_category_id

odopli94  于 2023-06-25  发布在  Go
关注(0)|答案(1)|浏览(84)

当我尝试通过发布以下JSON来创建新的职位发布时:

{
  "job_title": "Software Developer",
  "job_category": [
    {
      "id": 1,
      "name": "Engineering"
    },
    {
      "id": 2,
      "name": "IT"
    }
  ],
  "job_skills": [
    {
      "id": 1,
      "title": "DJ",
      "category": [
        {
          "id": 1,
          "name": "Web Development"
        },
        {
          "id": 2,
          "name": "Python"
        }
      ]
    },
    {
      "id": 2,
      "title": "RT",
      "category": [
        {
          "id": 3,
          "name": "Frontend Development"
        },
        {
          "id": 4,
          "name": "JavaScript"
        }
      ]
    }
  ],
  "job_salary_range": 80000,
  "job_description": "We are looking for a skilled software developer proficient in Django and React...",
  "job_type": {
    "id": 1,
    "job_type_choices": "FT"
  },
  "job_location": [
    {
      "id": 1,
      "name": "New York"
    },
    {
      "id": 2,
      "name": "San Francisco"
    }
  ],
  "job_level": [
    {
      "id": 1,
      "job_level_choices": "EL"
    },
    {
      "id": 2,
      "job_level_choices": "ML"
    }
  ],
  "job_application_link": "https://example.com/apply",
  "company_name": "ABC Company",
  "company_hq": "New York",
  "company_logo": "https://example.com/logo.png",
  "companys_website": "https://example.com",
  "company_contact_email": "info@example.com",
  "company_description": "ABC Company is a leading software development company...",
  "date_created": "2023-06-09T12:00:00Z",
  "date_updated": "2023-06-09T14:30:00Z"
}

我得到以下错误:

IntegrityError at /jobs/create

NOT NULL约束失败:afritechjobsapi_postajob.job_category_id
MODELS.PY

class Category(models.Model):
    name = models.CharField(max_length=50, unique=True, null=True, blank=True)

    def __str__(self):
        return self.name

class JobLocations(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name
    
class JobType(models.Model):
    class JobTypeChoices(models.TextChoices):
        CONTRACT = 'CT', 'Contract'
        FULLTIME = 'FT', 'FullTime'
        FREELANCE = 'FL', 'Freelance'
        INTERNSHIP = 'IP', 'Internship'
        PARTTIME = 'PT', 'Parttime'
    
    job_type_choices = models.CharField(max_length=2, choices=JobTypeChoices.choices, default=JobTypeChoices.FULLTIME)

class JobLevel(models.Model):
    class JobLevelChoices(models.TextChoices):
        STUDENT = 'ST', 'Student'
        INTERN = 'IN', 'Intern'
        ENTRYLEVEL = 'EL', 'Entrylevel'
        MIDLEVEL = 'ML', 'Midlevel'
        SENIORLEVEL = 'SL', 'Seniorlevel'
        COFOUNDER = 'CF', 'Cofounder'
        DIRECTOR = 'DC', 'Director'
        MANAGER = 'MG', 'Manager'
        CEO = 'CEO', 'ChiefExecutiveOfficer'
        CTO = 'CTO', 'ChiefTechnologyOfficer'
        CMO = 'CMO', 'ChiefMarketingOfficer'
        CFO = 'CFO', 'Chief Financial Officer'
        COO = 'COO', 'Chief Operating Officer'
    
    job_level_choices = models.CharField(max_length=3, choices=JobLevelChoices.choices, default=JobLevelChoices.ENTRYLEVEL)

class PostAJob(models.Model):
    job_title = models.CharField(max_length=200)
    job_category = models.ForeignKey(Category, on_delete=models.CASCADE)
    job_skills = models.ForeignKey(JobSkills, on_delete=models.SET_NULL, null=True, blank=True)
    job_salary_range = models.IntegerField(blank=True)
    job_description = models.TextField()
    job_type = models.ForeignKey(JobType, on_delete=models.CASCADE)
    job_location = models.ForeignKey(JobLocations, on_delete=models.CASCADE, default='')
    job_level = models.ForeignKey(JobLevel, on_delete=models.CASCADE)
    job_application_link = models.URLField(max_length=200)
    company_name = models.CharField(max_length=200)
    company_hq = models.CharField(max_length=200)
    company_logo = models.ImageField()
    companys_website = models.URLField(max_length=200)
    company_contact_email = models.EmailField(max_length=200, null=True, blank=True)
    company_description = models.TextField()
    date_created = models.DateTimeField(auto_now_add=True)
    date_updated = models.DateTimeField(auto_now=True)
    created_by = models.ForeignKey(Profile, on_delete=models.CASCADE)

    def __str__(self):
        return self.job_title

SERIALIZERS.PY

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = ['id', 'name']

class PostAJobSerializer(serializers.ModelSerializer):
    job_category = CategorySerializer(many=True)
    job_skills = JobSkillsSerializer(many=True)
    job_type = JobTypeSerializer()
    job_location = JobLocationsSerializer(many=True)
    job_level = JobLevelSerializer(many=True)
    created_by = ProfileSerializer()
    #companylogotoo

    class Meta:
        model = PostAJob
        fields = ['id', 'job_title', 'job_category', 'job_skills', 'job_salary_range', 'job_description', 'job_type', 'job_location', 'job_level', 'job_application_link',  'company_name', 'company_hq', 'companys_website', 'company_contact_email', 'company_description', 'date_created', 'date_updated', 'created_by']

    def create(self, validated_data):
        job_category_data = validated_data.pop('job_category')
        job_skills_data = validated_data.pop('job_skills')
        job_type_data = validated_data.pop('job_type')
        job_location_data = validated_data.pop('job_location')
        job_level_data = validated_data.pop('job_level')

        # Create the PostAJob instance
        post_a_job = PostAJob.objects.create(**validated_data)

        #create the related instances for job_category
        category = Category.objects.create(**job_category_data)
        post_a_job.job_category = category

        #create the related instances for job_skills
        for skills_data in job_skills_data:
            skills = JobSkills.objects.create(**skills_data)
            post_a_job.job_skills.add(skills)

        # Create the related instance for job_type
        job_type = JobType.objects.create(**job_type_data)
        post_a_job.job_type = job_type

        # Create the related instances for job_location
        for location_data in job_location_data:
            location = JobLocations.objects.create(**location_data)
            post_a_job.job_location.add(location)

        # Create the related instances for job_level
        for level_data in job_level_data:
            level = JobLevel.objects.create(**level_data)
            post_a_job.job_level.add(level)

        return post_a_job
type or paste code here

VIEWS.PY

@api_view(['POST'])
def post_a_job(request):
    if request.method == 'POST':
        post_a_job_serializer = PostAJobSerializer(data=request.data)
        if post_a_job_serializer.is_valid():
            post_a_job_serializer.save()
            return Response(post_a_job_serializer.data, status=status.HTTP_201_CREATED)
        return Response(post_a_job_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

从对类似问题的研究来看,Django REST Framework NOT NULL constraint failed-这主要发生在read-only = True时,但在我的最终情况并非如此

f3temu5u

f3temu5u1#

在设置类别之前,您正在创建PostAJob对象。所以当你创建一个对象时,category为null,你会得到错误。
你可以这样修改你的代码

class PostAJobSerializer(serializers.ModelSerializer):
    job_category = CategorySerializer(many=True)
    job_skills = JobSkillsSerializer(many=True)
    job_type = JobTypeSerializer()
    job_location = JobLocationsSerializer(many=True)
    job_level = JobLevelSerializer(many=True)
    created_by = ProfileSerializer()
    #companylogotoo

    class Meta:
        model = PostAJob
        fields = ['id', 'job_title', 'job_category', 'job_skills', 'job_salary_range', 'job_description', 'job_type', 'job_location', 'job_level', 'job_application_link',  'company_name', 'company_hq', 'companys_website', 'company_contact_email', 'company_description', 'date_created', 'date_updated', 'created_by']

    def create(self, validated_data):
        job_category_data = validated_data.pop('job_category')
        job_skills_data = validated_data.pop('job_skills')
        job_type_data = validated_data.pop('job_type')
        job_location_data = validated_data.pop('job_location')
        job_level_data = validated_data.pop('job_level')

        #create the related instances for job_category
        category = Category.objects.create(**job_category_data)
        
    
        # Create the PostAJob instance
        validated_data.update({"category": category})
        post_a_job = PostAJob.objects.create(**validated_data)


        #create the related instances for job_skills
        for skills_data in job_skills_data:
            skills = JobSkills.objects.create(**skills_data)
            post_a_job.job_skills.add(skills)

        # Create the related instance for job_type
        job_type = JobType.objects.create(**job_type_data)
        post_a_job.job_type = job_type

        # Create the related instances for job_location
        for location_data in job_location_data:
            location = JobLocations.objects.create(**location_data)
            post_a_job.job_location.add(location)

        # Create the related instances for job_level
        for level_data in job_level_data:
            level = JobLevel.objects.create(**level_data)
            post_a_job.job_level.add(level)

        return post_a_job

相关问题