gies0r
gies0r

Reputation: 5239

Python django serializer -> validated_data removes field

Goal: Add object to ManyToMany field of another DataModel.

Data model with ManyToMany field:

class ObservedDataModel(models.Model):
    domain_objects = models.ManyToManyField(DomainNameModel, blank=True)

Following code works, but the foreign object id is hardcoded ((ObservedDataModel, id=2)):

class DomainSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = DomainNameModel
        fields = ('url', 'id', 'name')

    def create(self, validated_data):
        domain_obj = DomainNameModel.objects.create(name=validated_data['name'])

        observed_data_object = get_object_or_404(ObservedDataModel, id=2)  # TODO !!!!!!
        observed_data_object.domain_objects.add(domain_obj)

        return domain_obj

To let the user set the (ObservedDataModel, id=X) i´ve tried to send a request {'name': 'apple.com', 'observeddata': 2}, but the validated_data field does not contain the variable observeddata.

So how can I add a custom (non-modell) field to the validated_data variable?

Upvotes: 0

Views: 1880

Answers (2)

zaidfazil
zaidfazil

Reputation: 9235

Override the init method of the serializer,

class DomainSerializer(serializers.HyperlinkedModelSerializer): 

    def __init__(self, obs_data, *args, **kwargs):
        super(DomainSerializer, self).__init__(*args, **kwargs)
        self.obs_data = obs_data

    class Meta: 
        model = DomainNameModel
        fields = ('url', 'id', 'name') 

    def create(self, validated_data):
        domain_obj = DomainNameModel.objects.create(name=validated_data['name'])
        observed_data_object = get_object_or_404(ObservedDataModel, id=self.obs_data) # here's the item....
        observed_data_object.domain_objects.add(domain_obj)
        return domain_obj

In the views,

DomainSerializer(data=your_data, obs_data=observed_data_id)

Upvotes: 0

gies0r
gies0r

Reputation: 5239

Just found the answer using the stackoverflow suggestion for my question (great feature!). The solution is to overwrite to_internal_value like below:

def to_internal_value(self, data):
    internal_value = super(DomainSerializer, self).to_internal_value(data)
    my_non_model_field_raw_value = data.get("observeddata")
    my_non_model_field_value = my_non_model_field_raw_value
    internal_value.update({
        "observeddata": my_non_model_field_value
    })
    return internal_value

Thanks to trubliphone

Upvotes: 4

Related Questions