I am wondering how I can get mongoengine and djangoRESTframework to work with each other. Currently, my model is
from mongoengine import *
import datetime
class Blog(Document):
post_id = IntField(unique=True)
title = StringField(max_length=144, required=True)
date_created = DateTimeField(default=datetime.datetime.now)
body = StringField(required=True)
and I have the serializer defined as
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import *
class BlogList(APIView):
"""
Lists all blog posts, or creates a new post
"""
def get(self, request, format=None):
posts = Blog.objects.to_json()
return Response(posts)
But I am receiving the error
TypeError at /blog/
__init__() takes exactly 1 argument (2 given)
Request Method: GET
Request URL: http://127.0.0.1:8000/blog/
Django Version: 1.5.1
Exception Type: TypeError
Exception Value:
__init__() takes exactly 1 argument (2 given)
which gives the following traceback
response = callback(request, *callback_args, **callback_kwargs)
Django REST Framework is intended to work well with Django's models. As MongoEngine is not a replacement for Django's Models, you will need to define a few more functions for it to play nice with Django Rest framework.
If you need a framework build for MongoEngine, you might want to take a look at django-tastypie-mongoengine instead.
If you prefer to use Django REST Framework it's perfectly feasible though. Your BlogList
class is actually a View, not a Serializer. First, define a serializer class:
from rest_framework import serializers
from .models import Blog
class BlogSerializer(serializers.Serializer):
post_id = serializers.IntegerField()
title = serializers.CharField(max_length=144)
date_created = serializers.DateTimeField(required=False)
body = serializers.CharField()
def restore_object(self, attrs, instance=None):
if instance is not None:
for k, v in attrs.iteritems():
setattr(instance, k, v)
return instance
return Blog(**attrs)
Since the MongoEngine Document is not a Django Model instance, you need to create the objects yourself instead of inheriting from serializers.ModelSerializer
. That is why the restore_object
method is here. From the documentation: Given a dictionary of deserialized field values, [it will] either update an existing model instance, or create a new model instance.
Then you can define your view, e.g.
from rest_framework import generics
from .models import Blog
class BlogList(generics.ListCreateAPIView):
serializer_class = BlogSerializer
def get_queryset(self):
return Blog.objects
Again, Django REST Framework expects a few things of a standard Django models which are not verified by MongoEngine Documents, hence the need to redefine the get_queryset
method.
Then in your urls.py, add:
url(r'^blog/', BlogList.as_view(), name='blog-list'),