can can - 29 days ago 12
Python Question

django rest type error fields is not JSON serializable

I am trying to implement simple rest api with django. However I am getting the following error,

enter image description here

//model.py

from django.db import models

# Create your models here.


class Event(models.Model):

name = models.TextField()
type = models.TextField()
location = models.TextField()
start_hour = models.TextField()
end_hour = models.TextField()
creator = models.TextField()

class Meta:
verbose_name = "Event"
verbose_name_plural = "Events"

def __str__(self):
return self.name


//serializer.py

from rest_framework import serializers
from .models import Event

class EventSerializer(serializers.ModelSerializer):

class Meta:
model = Event
fields = ('name', 'type')


//urls.py

from django.conf.urls import url
from django.contrib import admin
from rest_framework.urlpatterns import format_suffix_patterns
from events import views


urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^events/', views.EventList.as_view()),
]

urlpatterns = format_suffix_patterns(urlpatterns)


I am too new on django and I can't figure it out how to deal with this error. Please help me guys.

Answer

No problems with this set up, ripped from the tutorial.

Project folder django_example.

App folder events.

django_example/settings.py

Add:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'events.apps.EventsConfig'
]

Add:

events/apps.py

from __future__ import unicode_literals
from django.apps import AppConfig

class EventsConfig(AppConfig):
    name = 'events'

For context, events/models.py looks like this:

from __future__ import unicode_literals    
from django.db import models

# Create your models here.

class Event(models.Model):

    name = models.TextField()
    kind = models.TextField()
    location = models.TextField()
    start_hour = models.TextField()
    end_hour = models.TextField()
    creator = models.TextField()

    class Meta:
        verbose_name = "Event"
        verbose_name_plural = "Events"

    def __str__(self):
        return self.name

Don't use type as a field name.

Add:

events/serializers.py

from rest_framework import serializers
from .models import Event  
class EventSerializer(serializers.ModelSerializer):   
    class Meta:
        model = Event
        fields = ('name', 'kind')

events/views.py

Add:

from django.shortcuts import render

# Create your views here.

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from events.models import Event
from events.serializers import EventSerializer

class JSONResponse(HttpResponse):
    """
    An HttpResponse that renders its content into JSON.
    """
    def __init__(self, data, **kwargs):
        content = JSONRenderer().render(data)
        kwargs['content_type'] = 'application/json'
        super(JSONResponse, self).__init__(content, **kwargs)

@csrf_exempt
def event_list(request):
    """
    List all code snippets, or create a new snippet.
    """
    if request.method == 'GET':
        snippets = Event.objects.all()
        serializer = EventSerializer(snippets, many=True)
        return JSONResponse(serializer.data)

    elif request.method == 'POST':
        data = JSONParser().parse(request)
        serializer = EventSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return JSONResponse(serializer.data, status=201)
        return JSONResponse(serializer.errors, status=400)

@csrf_exempt
def event_detail(request, pk):
    """
    Retrieve, update or delete a code snippet.
    """
    try:
        event = Event.objects.get(pk=pk)
    except event.DoesNotExist:
        return HttpResponse(status=404)

    if request.method == 'GET':
        serializer = EventSerializer(snippet)
        return JSONResponse(serializer.data)

    elif request.method == 'PUT':
        data = JSONParser().parse(request)
        serializer = EventSerializer(event, data=data)
        if serializer.is_valid():
            serializer.save()
            return JSONResponse(serializer.data)
        return JSONResponse(serializer.errors, status=400)

    elif request.method == 'DELETE':
        event.delete()
        return HttpResponse(status=204)

events/urls.py

Add:

from django.conf.urls import url
from events import views

urlpatterns = [
    url(r'^events/$', views.event_list),
    url(r'^events/(?P<pk>[0-9]+)/$', views.event_detail),
]

Add:

django_example/urls.py

from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^', include('events.urls'))
]

If you ran your migrations after you populated models.py you should be able to see a response from your API, even if it's just an empty list.

Comments