首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >枚举Django Rest框架序列化程序中的模型选择

枚举Django Rest框架序列化程序中的模型选择
EN

Stack Overflow用户
提问于 2015-03-25 10:43:19
回答 3查看 7.2K关注 0票数 13

我有一个使用Django选项字段的模型,如下所示:

代码语言:javascript
复制
class Question(models.Model):
QUESTION_TYPES = (
    (10,'Blurb'),
    (20,'Group Header'),
    (21,'Group Footer'),
    (30,'Sub-Group Header'),
    (31,'Sub-Group Footer'),
    (50,'Save Button'),
    (100,'Standard Question'),
    (105,'Text-Area Question'),
    (110,'Multiple-Choice Question'),
    (120,'Standard Sub-Question'),
    (130,'Multiple-Choice Sub-Question')
)
type = models.IntegerField(default=100,choices=QUESTION_TYPES)

我正在使用Django Rest Framework将这个模型作为API呈现给一个Angular web应用程序。在我的Angular web应用程序中,我想要一个包含所有这些选项的组合框小部件。不是整数,而是文本选项,比如"blurb","standard blurb“等等。

现在,我可以将组合框手动编码到Angular应用程序中,但是本着DRY的精神,是否可以编写一个只返回这些选择(即QUESTION_TYPES对象)的DRF序列化程序,这样我就可以用ReST查询来填充组合框?

说到“可能”,我猜我的意思是“简单而优雅”。也许我的意思也是"ReSTful“。(这样做是ReSTful做的吗?)

只是想知道。。。

谢谢

约翰

EN

回答 3

Stack Overflow用户

发布于 2015-03-25 12:58:00

我可能会尝试下面这样的方法:

代码语言:javascript
复制
# models.py
class Question(models.Model):
    QUESTION_NAMES = (
        'Blurb',
        'Group Header',
        'Group Footer',
        'Sub-Group Header',
        'Sub-Group Footer',
        'Save Button',
        'Standard Question',
        'Text-Area Question',
        'Multiple-Choice Question',
        'Standard Sub-Question',
        'Multiple-Choice Sub-Question')
    QUESTION_VALS = (10, 20, 21, 30,
                     31, 50, 100, 105, 110,
                     120, 130)
    QUESTION_TYPES = tuple(zip(QUESTION_VALS, QUESTION_NAMES))
    # Personal choice here: I never name attribs after Python built-ins:
    qtype = models.IntegerField(default=100,choices=QUESTION_TYPES)

下面的代码不能像我想的那样工作

(以下是我对序列化对象列表的原始直觉,但它不起作用。我还是把它留在这里,因为它看起来应该可以工作。)

好的,我们有了一种方法来访问字符串本身,现在我们只需要序列化它们,为此,我可能会尝试使用ListField in DRF3,我认为它应该支持source kwarg?

代码语言:javascript
复制
# serializers.py
from .models import Question
class YourSerializer(ModelSerializer):
    names = serializers.ListField(
       child=serializers.CharField(max_length=40),
       source=Question.QUESTION_NAMES
    )
    class Meta:
        model = Question
        fields = ('names', etc.)

下面返回了一个结果列表

回退:使用SerializerMethodField

代码语言:javascript
复制
from .models import Question

class YourSerializer(serializers.ModelSerializer):
    ...
    names = serializers.SerializerMethodField()

    def get_names(self, obj):
        return Question.QUESTION_NAMES

    class Meta:
        model = Question

演示:

代码语言:javascript
复制
In [1]: q = Question.objects.create()
Out[1]: <Question: Question object>  

In [2]: ser = YourSerializer(q)

In [3]: ser.data
Out[3]: {'id': 1, 'names': ['Blurb', 'Group Header', 'Group Footer', 'Sub-Group Header', 'Sub-Group Footer', 'Save Button', 'Standard Question', 'Text-Area Question', 'Multiple-Choice Question', 'Standard Sub-Question', 'Multiple-Choice Sub-Question'], 'qtype': 100}
票数 5
EN

Stack Overflow用户

发布于 2017-05-02 07:34:55

如果将ModelViewSetModelSerializer结合使用,则OPTIONS请求将返回可用于获取选项的元数据。

代码语言:javascript
复制
from models import Question
from rest_framework import serializers

class QuestionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Question


from rest_framework.viewsets import ModelViewSet
class QuestionChoicesViewSet(ModelViewSet):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer

这将为您提供一个包含actions属性的响应,可能如下所示:

代码语言:javascript
复制
"actions": {
    "POST": {
        "id": {
            "type": "integer",
            "required": false,
            "read_only": true,
            "label": "ID"
        },
        "qtype": {
            "type": "choice",
            "required": false,
            "read_only": false,
            "label": "Qtype",
            "choices": [
                {
                    "display_name": "Blurb",
                    "value": 10
                },
                {
                    "display_name": "Group Header",
                    "value": 20
                },
                {
                    "display_name": "Group Footer",
                    "value": 21
                },
                {
                    "display_name": "Sub-Group Header",
                    "value": 30
                },
                //...
        }
    }
}

您可以遍历qtype上的choices属性,以获得所有可用的选项。

要更熟悉这个主题,可以阅读:Metadata

票数 5
EN

Stack Overflow用户

发布于 2016-02-11 22:16:14

我通过为只使用GET动词的选择创建一个API端点来实现这一点。

models.py

代码语言:javascript
复制
QUESTION_TYPES = (
    (10,'Blurb'),
    (20,'Group Header'),
    (21,'Group Footer'),
    (30,'Sub-Group Header'),
    (31,'Sub-Group Footer'),
    (50,'Save Button'),
    (100,'Standard Question'),
    (105,'Text-Area Question'),
    (110,'Multiple-Choice Question'),
    (120,'Standard Sub-Question'),
    (130,'Multiple-Choice Sub-Question')
)

class Question(models.Model):
    type = models.IntegerField(default=100,choices=QUESTION_TYPES)

viewsets.py

代码语言:javascript
复制
from models import QUESTION_NAMES, Question
from rest_framework import serializers
class QuestionSerializer(serializers.ModelSerializer):
    type = serializers.ChoiceField(choices=QUESTION_NAMES, default=100)
    class Meta:
        model = Question

from rest_framework.response import Response
from rest_framework.views import APIView
class QuestionChoicesViewSet(APIView):
    def get(self, request):
        return Response(QUESTION_NAMES)

from rest_framework import viewsets
class QuestionViewSet(viewsets.ModelViewSet):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29246559

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档