Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 789
Bat Avatar asked Sep 06 '25 23:09

Bat


1 Answers

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)

like image 117
Bat Avatar answered Sep 08 '25 21:09

Bat