Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django REST framework: AttributeError: Serializer object has no attribute 'Meta'

Given the following model and serializer for a Django REST framework setup:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from django.db import models

class StationReport(models.Model):

    water_level = models.IntegerField(max_length=5, blank=False)
    user_name = models.CharField(max_length=256, blank=False)
    email_address = models.CharField(max_length=256, blank=True)
    recorded_at = models.DateTimeField(blank=False)
    created_at = models.DateTimeField(auto_now_add=True)
    modified_at = models.DateTimeField(auto_now_add=True)

...

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from rest_framework import serializers
from models import StationReport

class StationReportSerializer(serializers.HyperlinkedModelSerializer):
    water_level = serializers.IntegerField(required=True)
    user_name = serializers.CharField(required=True)
    email_address = serializers.CharField(required=False)
    recorded_at = serializers.DateTimeField(required=True)

    def create(self, validated_data):
        return StationReport.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.water_level = validated_data.get('water_level', instance.water_level)
        instance.user_name = validated_data.get('user_name', instance.user_name)
        instance.email_address = validated_data.get('email_address', instance.email_address)
        instance.recorded_at = validated_data.get('recorded_at', instance.recorded_at)
        instance.save()
        return instance

Why am I receiving this AttributeError when I visit http://localhost:8000/stationreports/?

AttributeError at /stationreports/

'StationReportSerializer' object has no attribute 'Meta'

Request Method:     GET
Request URL:    http://localhost:8000/stationreports/
Django Version:     1.7.3
Exception Type:     AttributeError
Exception Value:    

'StationReportSerializer' object has no attribute 'Meta'

I followed the first part of the Serializers tutorial which does not seem to work in the presented form. I already tried to remove the Meta class in the model but still the error occurs.

The problem reason

For some reason I did not exactly follow the mentioned Serializers tutorial. My given example works when I change the following:

Before:

class GaugeReportSerializer(serializers.HyperlinkedModelSerializer):
    water_level = serializers.IntegerField(required=True, max_length=5)

After:

class GaugeReportSerializer(serializers.Serializer):
    water_level = serializers.IntegerField(required=True)

I think this mistake happened because I did the Quickstart tutorial before.

like image 231
JJD Avatar asked Jan 14 '15 16:01

JJD


2 Answers

Because you don't have a Meta class defined.

In Django REST Framework, Meta classes are not inherited from their parent classes.

class StationReportSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = StationReport

The above should solve your problem.

http://www.django-rest-framework.org/api-guide/serializers/#inheritance-of-the-meta-class

like image 142
dursk Avatar answered Oct 11 '22 16:10

dursk


HyperlinkedModelSerializer is a model serializer. So you need to define the class Meta like below:

Moreover, when you set the model on meta class, then you don't need to explicitly define all of the fields on serializer. You just add them to the fields of meta class. Unless your are doing something specialized on the fields.

class StationReportSerializer(serializers.HyperlinkedModelSerializer):

    # ...

    class Meta:
        model = StationReport
        fields = ( 
            'water_level',
            'user_name',
            'email_address',
            'recorded_at',
        )

    extra_kwargs = {
        'water_level': {'required': True},
        'user_name': {'required': True},
        'email_address': {'required': False},
        'recorded_at': {'required': True},
    } 
like image 30
Sam R. Avatar answered Oct 11 '22 18:10

Sam R.