Bat
Bat

Reputation: 173

Django nested serializer allow_null=True

I have a nested serializer and I want to activate the allow_null to true, but it doesn't work.

TOP object have a nested Down object, the related_name must be present in the TOP object but with a null value. If the down object is not null all down object fields are required.

Example request with all fields in down object (this one works fine) :

{
  "title": "Titre new rgfdgfdgthtrh",
  "downs": {
     "type": "Type example",
     "is_external": true,
  },
}

Example that i tryed to do : request when down object is null (this one doesn't work)

{
  "title": "Titre new ",
  "downs": {},
}

I have tryed with "downs": None or Null without success.

My views :

# My Views.py

class Top(models.Model):
  class Meta:
    verbose_name = _('Top')
    verbose_name_plural = _('Tops')

  top_guid = models.UUIDField(
    primary_key=True,
    unique=True,
    default=uuid.uuid4,
    editable=False)

  title = models.CharField(
    help_text=_('Title'),
    verbose_name=_('title'),
    max_length=100,
    blank=False
)


class Down(models.Model):
  top = models.OneToOneField(
    Top,
    on_delete=models.CASCADE,
    help_text=_('Top'),
    verbose_name="top",
    related_name="downs"
  )

  type = models.CharField(
    help_text=_('Type'),
    verbose_name=_('type'),
    max_length=30,
    blank=False
  )

  is_external = models.BooleanField(
    help_text=_('external (default = false)'),
    verbose_name=_('external'),
    blank=False,
    default=False
  )

and my serializers

# My serializers.py

class DownSerializer(serializers.ModelSerializer):
  class Meta:
    model = Down
    fields = '__all__'


class TopSerializer(serializers.ModelSerializer):
  downs = DownSerializer(many=False, required=False, allow_null=True)

  class Meta:
    model = Top
    fields = ('top_guid', 'title', 'downs',)

  def create(self, validated_data):
    """
    Create and return a new `Topic` instance.
    """
    downs_data = validated_data.pop('downs')
    top = Top.objects.create(**validated_data)
    Down.objects.create(top=top, **downs_data)
    return top

  def update(self, instance, validated_data):
    """
    Update and return an existing `Topic` instance.
    """
    # get bim_snippet data and bim_snippet object
    downs_data = validated_data.pop('downs')
    downs = instance.downs

    # update top data and save top object
    instance.title = validated_data.get('title', instance.title)
    instance.top_type = validated_data.get('top_type', instance.top_type)
    instance.save()

    # update down data and save down object
    downs.snippet_type = downs_data.get('type', downs.snippet_type)
    downs.is_external = downs_data.get('is_external', downs.is_external)
    downs.save()

    return instance

Thank's a lot.

Upvotes: 4

Views: 18032

Answers (1)

Bat
Bat

Reputation: 173

I think that if you add arguments like allow_null=True or read_only=False in your serializer class, you need to recreate your sqlite3 database. read_only was not working, but just after recreate the db it works fine. (makemigrations and migrate seem's to be not enought)

Upvotes: 5

Related Questions