【问题标题】:Getting mongoengine and django rest framework to play nice让 mongoengine 和 django rest 框架玩得很好
【发布时间】:2013-06-20 18:56:49
【问题描述】:

我想知道如何让 mongoengine 和 djangoRESTframework 相互协作。目前,我的模型是

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)

我将序列化程序定义为

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)

但我收到错误提示

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)

给出以下回溯

response = callback(request, *callback_args, **callback_kwargs)

【问题讨论】:

    标签: django mongoengine django-rest-framework


    【解决方案1】:

    Django REST Framework 旨在与 Django 的模型一起工作。由于 MongoEngine 不是 Django 模型的替代品,因此您需要定义更多函数才能使其与 Django Rest 框架配合使用。

    如果您需要为 MongoEngine 构建框架,您可能需要查看django-tastypie-mongoengine

    如果您更喜欢使用 Django REST Framework,那么它是完全可行的。你的BlogList 类实际上是一个视图,而不是一个序列化器。首先,定义一个序列化器类:

    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)
    

    由于 MongoEngine Document 不是 Django Model 实例,您需要自己创建对象,而不是从 serializers.ModelSerializer 继承。这就是restore_object 方法在这里的原因。来自documentation:给定一个反序列化字段值的字典,[它将]更新现有模型实例,或创建一个新模型实例。

    然后你可以定义你的视图,例如

    from rest_framework import generics
    from .models import Blog
    
    class BlogList(generics.ListCreateAPIView):
        serializer_class = BlogSerializer
    
        def get_queryset(self):
            return Blog.objects
    

    再次,Django REST Framework 需要标准 Django 模型的一些东西,这些东西没有被 MongoEngine 文档验证,因此需要重新定义 get_queryset 方法。

    然后在你的 urls.py 中,添加:

    url(r'^blog/', BlogList.as_view(), name='blog-list'),
    

    【讨论】:

    【解决方案2】:

    查看Monkful,它类似于 Django Rest Framework,但可以与 MongoEngine 一起使用。

    【讨论】:

    • 这个工具是为 Flask 构建的,问题是针对 Django 的。
    【解决方案3】:

    快进到 2016 年年中。现在我们有Django-REST-Framework-Mongoengine。它距离成为一个完整的交钥匙解决方案还有很长的路要走,但至少它目前提供的部分功能已经被单元测试很好地覆盖了。所以,来吧,让我们改进它。

    【讨论】:

    • 不管它的功能如何,它在生产中是否稳定?
    • @Ahmed 不,不是。但我们越来越近了。我们在公司内运行了几项内部服务,它为我们提供了很好的服务。
    猜你喜欢
    • 1970-01-01
    • 2015-04-30
    • 2014-03-18
    • 2014-10-02
    • 2011-09-14
    • 2011-09-17
    • 2010-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多