user7279462
user7279462

Reputation: 23

passing None to a foreign key while saving a serialiser in Django Rest Framework

Here is a model for header,

class Header(models.Model):
    id = models.AutoField(primary_key=True)
    features = models.ForeignKey(Project, null=True, blank=True, related_name= 'features')
    def __str__(self):
        return str(self.name)

and this the model for Project (the foreign key of features in Header):

class Project(models.Model):
    id = models.AutoField(primary_key=True)
    project_info = models.OneToOneField(ProjectInfo, related_name='project_info')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    dataset_associated = models.ForeignKey(Dataset)  
    ratio_test_training = models.IntegerField()
    random_seed = models.IntegerField(blank=True, null=True) 
    url = models.URLField(blank=True, null=True)
    def __str__(self):
        return str(self.project_info.name)

And, when I am trying to save Header serializer by passing None to features, it shows an error that :

{features: ["This field may not be null."]}

even when I have set its property of null = True.

This is the serializer for Header:

class HeaderSerializer(serializers.ModelSerializer):
                features = ProjectSerializer()
                class Meta:
                        model = models.Header
                        fields = ('id', 'features') 
                def create(self, validated_data):
                        features_data = validated_data.pop("features")
                        if(features_data):
                                      features = models.Project.objects.get(pk =
                        (features_data.get("id")))
                        else:
                               features = None
                        obj=models.Header.objects.create(features = features)
                        obj.save()
                        return obj

And this is the code in views.py,

@api_view(['GET', 'POST', 'DELETE'])
def header_detail_pk(request):
    if request.method == 'POST':
        features = request.POST.get('features')
        if(features):
            features = project_serializer.data
            print("Not none")
        else:
            features = None
        serializer = HeaderSerializer('features':features)
        if serializer.is_valid():
            serializer.save(features= features)
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

This is the Project serializer :

class ProjectSerializer(serializers.ModelSerializer):
        project_info = ProjectInfoSerializer()
        dataset_associated = DatasetSerializer()
        class Meta:
                model = models.Project
                fields = ('id', 'project_info','created_at', 'updated_at', 'dataset_associated', 'ratio_test_training', 'random_seed', 'url')
        def create(self, validated_data):
                project_info_data = validated_data.pop("project_info")
                dataset_associated_data = validated_data.pop("dataset_associated")
                project_info_id = project_info_data.get("id")
                dataset_associated_id = dataset_associated_data.get("dataset_id")
                project_info = models.ProjectInfo.objects.get(pk=project_info_id)
                dataset_associated = models.Dataset.objects.get(dataset_id=dataset_associated_id)
                obj = models.Project.objects.create(url = validated_data.get("url") ,ratio_test_training=validated_data.get("ratio_test_training"), random_seed=validated_data.get("random_seed"), project_info=project_info, dataset_associated=dataset_associated)
                obj.save()
                return obj

Upvotes: 2

Views: 895

Answers (1)

UserGraund
UserGraund

Reputation: 310

first variant

 class HeaderSerializer(serializers.ModelSerializer):
                class Meta:
                        model = models.Header

# Second variant

class HeaderSerializer(serializers.ModelSerializer):
                features = ProjectSerializer(allow_null=True)
                class Meta:
                        model = models.Header
                        fields = ('id', 'features') 
                def create(self, validated_data):
                        features_data = validated_data.pop("features")
                        if(features_data):
                                      features = models.Project.objects.get(pk =
                        (features_data.get("id")))
                        else:
                               features = None
                        obj=models.Header.objects.create(features = features)
                        obj.save()
                        return obj

Parameter in ProjectSerializer can change depends on version of your DRF, also I think you don't need to override the create method

Upvotes: 2

Related Questions