How to display all model fields with ModelSerializer?

Question:

models.py:

class Car():
    producer = models.ForeignKey(Producer, blank=True, null=True,)
    color = models.CharField()
    car_model = models.CharField()
    doors = models.CharField()

serializers.py:

class CarSerializer(ModelSerializer):

    class Meta:
        model = Car
        fields = Car._meta.get_all_field_names()

So, here I want to use all fields. But I have an error:

Field name producer_id is not valid for model Car.

How to fix that?

Thanks!

Asked By: Leon

||

Answers:

According to the Django REST Framework’s Documentation on ModelSerializers:

By default, all the model fields on the class will be mapped to a corresponding serializer fields.

This is different than Django’s ModelForms, which requires you to specify the special attribute '__all__' to utilize all model fields. Therefore, all that is necessary is to declare the model.

class CarSerializer(ModelSerializer):
    class Meta:
        model = Car

Update (for versions >= 3.5)

The behaviour described above was deprecated in version 3.3, and forbidden since version 3.5.

It is now mandatory to use the special attribute '__all__' to use all fields in the Django REST Framework, same as Django Forms:

Failing to set either fields or exclude raised a pending deprecation warning in version 3.3 and raised a deprecation warning in 3.4. Its usage is now mandatory.

So now it must be:

class CarSerializer(ModelSerializer):
    class Meta:
        model = Car
        fields = '__all__'
Answered By: Michael B

You could use fields = '__all__' to get all your fields or you could specify if you want a limited number of fields to be returned. See documentation.

But this returns the id value for the foreign key field i.e. producer in your case. To get all the fields for producer, you need to create a serializer class for that too. See here.

So your updated serializers.py should be:

class ProducerSerializer(ModelSerializer):
    class Meta:
        model = Producer

class CarSerializer(ModelSerializer):
    producer= ProducerSerializer(read_only=True)

    class Meta:
        model = Car
        fields = ('producer', 'color', 'car_model', 'doors', )
Answered By: Venu Saini

if you want all fields to be included in the serializer you can use fields = '__all__':

class CarSerializer(serializer.ModelSerializer):
      class Meta:
           fields = '__all__'
           model = Car

But this approach is not recommended. We should always explicitly specify all fields. This is because it gives us control over fields displayed. If we don’t want a field’s data to be displayed, we can avoid that.

 class CarSerializer(serializer.ModelSerializer):
          class Meta:
               fields = ['name', 'color', 'company', 'price', ]
               model = Car
Answered By: Sarath Chandran K