python - Django REST Framework - 通过路由器将模型传递给 ViewSet

标签 python django python-2.7 django-models django-rest-framework

我正在尝试创建一个没有预定义模型的 REST-ModelViewSet,但在向路由器注册时会采用一个模型。我需要它来动态地将模型添加到我的 REST-API,而不需要配置任何新的 View 集或序列化器。

我的想法是通过 kwargs 中的模型的__init__ ,但我不知道如何正确地做到这一点。这是我尝试过的:

//Viewset
class ThemeViewSet(viewsets.ModelViewSet):
    def __init__(self, **kwargs):
        self.model = kwargs['model']
        self.serializer_class = None
        super(ThemeViewSet, self).__init__(**kwargs)

    def get_serializer_class(self):
        if self.serializer_class is not None:
            return self.serializer_class

        class ThemeSerializer(serializers.HyperlinkedModelSerializer):
            class Meta:
                model = self.model

        self.serializer_class = ThemeSerializer
        return self.serializer_class

//Router:
router = routers.DefaultRouter()
router.register(r'mytheme', ThemeViewSet(model=mytheme), base_name='mytheme')

现在,如果我尝试 print self.model__init__ ,它正确显示 <class 'myapp.models.mytheme'>在控制台中,但 Django 仍然返回错误:

AttributeError at /api/mytheme/
This method is available only on the view class.

此错误是由 classonlymethod 引发的-装饰器。我真的不知道该怎么做,有什么方法可以将模型传递给 __init__ ,或者我可以尝试其他方法吗?

(我知道 wq.db.rest 有一个路由器可以实现我想要的功能,但我不想使用 wq。我还没有尝试过 tastypie,这会让它变得更容易/可能吗?)

提前致谢!

最佳答案

Django REST Framework 期望 a ViewSet class被传递到路由器,而不是 View 实例。这是因为必须为每个请求创建实例,这可以防止共享状态带来的许多丑陋问题,并且还遵循标准的 Django 基于类的 View 。

如果您有一种方法可以根据传入的模型创建自定义的 ViewSet 类,那么您可能会运气更好:

class ThemeViewSet(viewsets.ModelViewSet):

    @classmethod
    def create_custom(cls, **kwargs):
        class CustomViewSet(cls):
            model = kwargs["model"]
            queryset = kwargs["model"].objects.all()

        return CustomViewSet

请注意,我还为 View 设置了queryset,并且自 2.4 发布以来,DRF 不再只接受model

这将在每次调用时创建一个新类,并且模型将自动设置为传递给它的模型。当向路由器注册它时,您将执行以下操作:

router.register(r'mytheme', ThemeViewSet.create_custom(model=mytheme), base_name='mytheme')

这样,您仍然会将 ViewSet 类传递给路由器,但它将针对传入的模型进行自定义。您必须确保设置 base_name,否则路由器将无法生成 View 名称,您最终会遇到错误。

关于python - Django REST Framework - 通过路由器将模型传递给 ViewSet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26914459/

相关文章:

python - subprocess.Popen 在做什么可能会导致 "Software caused connection abort"?

Python - 循环浏览大列表并快速下载图像

python - Django - TypeError at/statements/int() 参数必须是字符串、类似字节的对象或数字,而不是 'AnonymousUser'

python - 值错误 : Unable to configure handler 'file' : [Errno 13] Permission denied:

python-2.7 - 创建 AWS SNS 主题并使用 troposhere 在 ASG 中引用它

Python 可能的舍入错误?

python - 如何告诉 tox 不要从依赖项收集测试?

django - 使用 django-jenkins 运行覆盖测试

django - 如何为 Python 3.5 安装 Psycopg2

python - 导入错误 : No module named prop2part (TuLiP)