【问题标题】:Serializer inheriting from ModelForm and field type/form type序列化器继承自 ModelForm 和字段类型/表单类型
【发布时间】:2015-06-18 21:27:00
【问题描述】:

我有一个序列化程序(django rest 框架)可以根据 get 请求返回模型对象:

class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel

在我的视图中实例化这个序列化器后,我使用 serializer.data 返回所有字段的键/值:

class MyModelAPIView(APIView):    
    def get(self, request, **kwargs):
        obj_pk = kwargs.get('pk')
        obj = MyModel.objects.get(pk=obj_pk)
        serializer = serializers.MyModelSerializer(obj)
        return Response(serializer.data)

这是 json 中返回的示例:

{"firstname": "John", "lastname": "doe", "active": true}

但是,我正在使用 JavaScript 从中生成一个表单(动态生成的表单),并且我想知道每个键/对值是什么类型的字段,因此我可以相应地生成表单。我正在尝试对 ModelSerializer 进行子类化,以便返回的 JSON 如下所示:

{"firstname": {"value": "john", "type": "TextField"},
 "lastname": {...},
 "active": {"value": true, "type": "BooleanField"}}

这将允许我在我的表单中生成正确的输入类型。得到这个的最好方法是什么? 可能有一种更简单的方法可以使用与此完全不同的 Rest Framework 从 JSON 响应动态生成表单(希望不那么乏味)。如果是这样,我也有兴趣了解它!

谢谢,

【问题讨论】:

  • 这种技术的一个警告是,如果该字段是多项选择,我只会在需要所有值来动态创建表单下拉列表时获取当前值。因此,希望有一种更直接的方法来获取从 JSON 生成的表单。
  • 旁注,您为什么没有在序列化程序上声明您的字段?即fields=['firstname', 'last name']无需为此覆盖get方法。
  • 原因不多。我试图操纵视图中的响应数据,这就是原因。
  • 我一直在研究的潜在解决方案之一是 HTMLFormRenderer,它可以为我处理大部分繁重的工作。这里有潜在的好方向吗?
  • 我想到了两种方法。您可以读取字段元数据,即firstname .`get_internal_type()model._meta.get_field('firstname').get_internal_type。或者您可以自己在数据库中描述数据并将其添加为嵌套序列化程序。这将需要您重新设计模型。

标签: django django-models django-forms django-rest-framework


【解决方案1】:

而不是朝着修改 JSON 数据的方向前进。我创建了一个新的渲染器,灵感来自 HTMLFormRenderer 和 JSONRenderer。我遍历 data.fields.values 生成一个 json 数组,其中包含带有标签、帮助文本和转义 HTML 中的实际字段的对象。所以我的 ajax 动态表单可以轻松快速地定制。

【讨论】:

    【解决方案2】:

    例子:

    序列化器:

    class UserSerializer(serializers.HyperlinkedModelSerializer):
        class Meta:
            model = User
            fields = ('url', 'username', 'email', 'groups')
    

    查看:

    class UserViewSet(viewsets.ModelViewSet):
        """
        API endpoint that allows users to be viewed or edited.
        """
        queryset = User.objects.all()
        serializer_class = UserSerializer
    

    网址路由器:

    router = routers.DefaultRouter()
    router.register(r'users', views.UserViewSet)
    
    # Wire up our API using automatic URL routing.
    # Additionally, we include login URLs for the browsable API.
    urlpatterns = [
        url(r'^', include(router.urls)),
        url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
    ]
    

    在官方文档上查看这个快速入门文档; http://www.django-rest-framework.org/tutorial/quickstart/

    关于表单的渲染; Django REST 框架 - JSON API 文档:http://drf-json-api.readthedocs.org/en/latest/

    这仅用作渲染器和解析器,不提供 JSON API 可能预期的任何附加功能。

    class ExampleView(generics.ListAPIView):
        renderer_classes = (JsonApiRenderer, )
    

    settings.py

    REST_FRAMEWORK = {
        "DEFAULT_RENDERER_CLASSES": (
            "rest_framework_json_api.renderers.JsonApiRenderer",
            "rest_framework.renderers.BrowsableAPIRenderer",
            # Any other renderers
        ),
        "DEFAULT_PARSER_CLASSES": (
            "rest_framework_json_api.parsers.JsonApiParser",
            "rest_framework.parsers.FormParser",
            "rest_framework.parsers.MultiPartParser",
            # Any other parsers
        ),
    }
    

    希望对你有帮助!

    【讨论】:

      猜你喜欢
      • 2010-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-08
      • 1970-01-01
      • 2011-05-23
      • 1970-01-01
      相关资源
      最近更新 更多