Jenia Be Nice Please
Jenia Be Nice Please

Reputation: 2693

How to save an array of objects with Django Rest Framework

I have this json code:

{
  "word" : "world",
  "days" : ["tuesday", "thursday"]
}

And DRF gives me this error:

'days': [{'non_field_errors': ['Invalid data. Expected a dictionary, but got string.']}, 

This is my days serializer:

class DaysSerializer(serializers.ModelSerializer):
    class Meta:
        model = Days
        fields = ('day')

And this my top level serializer:

class WordsSerializer(serializers.ModelSerializer):
    days = DaysSerializer(many=True)
    class Meta:
          model = Words
          fields = ('word', 'days')

The Days model is:

class Days(models.Model):
    DAYS = (
        ("sunday", "Sunday"),
        ("monday", "Monday"),
        ("tuesday", "Tuesday"),
        ("wednesday", "Wednesday"),
        ("thursday", "Thursday"),
        ("friday", "Friday"),
        ("saturday", "Saturday"))

    day = models.TextField(choices=DAYS)

I want to emphasize that the input:

"days" : ["tuesday", "thursday"]

are the values not the keys in the Days table.

I read that I need to use bulk serializers. Is that the route that is recommended today? Or there is a simpler way?

If I need to use the bulk serializer library, I don't understand from their example how I could use that library for my purposes? Namely to (bulk) save the many to many entries (the Days) with one of the records (the Word).

P.S.

By the way, the relation between days and Words is M2M with no through field. Just plain M2M

P.S (2)

The way that I image this should work is DRF will look in the Days table and try to find the Day where the day column equals tuesday and make a M2M.

If it's not there, DRF needs to create the record and then make the M2M.

Same thing for thursday.

Upvotes: 1

Views: 3385

Answers (2)

Sagar Ramachandrappa
Sagar Ramachandrappa

Reputation: 1461

There are multiple ways you can represent relational field in DRF serializers. For your specific case SlugRelatedField suits better.

class WordsSerializer(serializers.ModelSerializer):
    days = serializers.SlugRelatedField(many=True, slug_field='day`)

    class Meta:
        model = Words
        fields = ('word', 'days')

But remember

When using SlugRelatedField as a read-write field, you will normally want to ensure that the slug field corresponds to a model field with unique=True.

Upvotes: 1

shlomta1
shlomta1

Reputation: 148

If I understand correctly you trying to pass 'days' as list of primary keys, if that the case try to change your serializer to this form:

class WordsSerializer(serializers.ModelSerializer):
days=serializers.PrimaryKeyRelatedField(queryset=Days.objects.all(),many=True)
class Meta:
      model = Words
      fields = ('word', 'days')

The error that you received raised because DRF expecting to get list of objects by default when you using your own model serializer to serialize fields. You can read more about it in DRF docs.

Upvotes: 1

Related Questions