Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 如何发送选项字段的关联值_Django_Django Rest Framework - Fatal编程技术网

Django 如何发送选项字段的关联值

Django 如何发送选项字段的关联值,django,django-rest-framework,Django,Django Rest Framework,我有一个名为Ticket的模型,带有一个选择字段status: STATUS_CHOICES = ( ('1', 'Open'), ('2', 'Resolved'), ('3', 'Won\'t fix') ) status = models.CharField( "Status", max_length=1, choices=STATUS_CHOICES, blank=False, default='1' ) 我正在为API使

我有一个名为
Ticket
的模型,带有一个选择字段
status

STATUS_CHOICES = (
    ('1', 'Open'),
    ('2', 'Resolved'),
    ('3', 'Won\'t fix')
)
status = models.CharField(
    "Status",
    max_length=1,
    choices=STATUS_CHOICES,
    blank=False,
    default='1'
)
我正在为API使用Django rest框架。默认模型序列化程序发送选择的第一个值,即
1
,而不是
Open
。如何使其发送第二个文本值作为响应

以下是我的序列化程序的一部分:

class TicketSerializer(serializers.ModelSerializer):
    status = serializers.ChoiceField(choices=Ticket.STATUS_CHOICES)        

    class Meta:
        model = Ticket
        fields = ('status', )

API通常用于获取数据,而不是数据的UI表示。在
('1','Choice 1')
中,
'1'
是要在任何地方存储和使用的值,
'Choice 1'
是我们需要时(在UI即模板中)需要显式使用的UI表示形式

DjangoAdmin是一个完整的Django应用程序,因此它显式地使用UI表示。如果您使用Django表单,您也需要显式地使用它。它不是自动使用的

在模板中,如果您执行
{{my\u form\u choice\u field.value}
操作,它将使用
'1'
而不是
'choice 1'
。您需要显式使用
{{my\u form\u choice\u field.get\u my\u form\u choice\u field\u display}
(在UI层中)来获取
'choice 1'

所以,正如我从API开始所说的,API通常用于获取数据,而不是它的UI表示。这就是为什么(与DJANGO一样)DjangoRestFramework也只使用原始值,而不使用其UI表示

如果您确实想返回UI表示,现在回答您的问题。然后,您需要重写BaseSerializer的
to_表示法
方法,以将值替换为其UI表示法,并重写
to_internal_值
以在保存时将UI表示法替换回值

您可以看到一个示例(从文档中)

引用上面链接的文档示例代码

class HighScoreSerializer(serializers.BaseSerializer):
    def to_internal_value(self, data):
        score = data.get('score')
        player_name = data.get('player_name')

        # Perform the data validation.
        if not score:
            raise ValidationError({
                'score': 'This field is required.'
            })
        if not player_name:
            raise ValidationError({
                'player_name': 'This field is required.'
            })
        if len(player_name) > 10:
            raise ValidationError({
                'player_name': 'May not be more than 10 characters.'
            })

        # Return the validated values. This will be available as
        # the `.validated_data` property.
        return {
            'score': int(score),
            'player_name': player_name
        }

    def to_representation(self, obj):
        return {
            'score': obj.score,
            'player_name': obj.player_name
        }

    def create(self, validated_data):
        return HighScore.objects.create(**validated_data)

API通常用于获取数据,而不是数据的UI表示。在
('1','Choice 1')
中,
'1'
是要在任何地方存储和使用的值,
'Choice 1'
是我们需要时(在UI即模板中)需要显式使用的UI表示形式

DjangoAdmin是一个完整的Django应用程序,因此它显式地使用UI表示。如果您使用Django表单,您也需要显式地使用它。它不是自动使用的

在模板中,如果您执行
{{my\u form\u choice\u field.value}
操作,它将使用
'1'
而不是
'choice 1'
。您需要显式使用
{{my\u form\u choice\u field.get\u my\u form\u choice\u field\u display}
(在UI层中)来获取
'choice 1'

所以,正如我从API开始所说的,API通常用于获取数据,而不是它的UI表示。这就是为什么(与DJANGO一样)DjangoRestFramework也只使用原始值,而不使用其UI表示

如果您确实想返回UI表示,现在回答您的问题。然后,您需要重写BaseSerializer的
to_表示法
方法,以将值替换为其UI表示法,并重写
to_internal_值
以在保存时将UI表示法替换回值

您可以看到一个示例(从文档中)

引用上面链接的文档示例代码

class HighScoreSerializer(serializers.BaseSerializer):
    def to_internal_value(self, data):
        score = data.get('score')
        player_name = data.get('player_name')

        # Perform the data validation.
        if not score:
            raise ValidationError({
                'score': 'This field is required.'
            })
        if not player_name:
            raise ValidationError({
                'player_name': 'This field is required.'
            })
        if len(player_name) > 10:
            raise ValidationError({
                'player_name': 'May not be more than 10 characters.'
            })

        # Return the validated values. This will be available as
        # the `.validated_data` property.
        return {
            'score': int(score),
            'player_name': player_name
        }

    def to_representation(self, obj):
        return {
            'score': obj.score,
            'player_name': obj.player_name
        }

    def create(self, validated_data):
        return HighScore.objects.create(**validated_data)

下面的方法解决了这个问题。我们可以为选项创建自定义字段

class ChoicesField(serializers.Field):
    def __init__(self, choices, **kwargs):
        self._choices = choices
        super(ChoicesField, self).__init__(**kwargs)

    def to_representation(self, obj):
        return self._choices[int(obj) - 1]  # obj is the first value

    def to_internal_value(self, data):
        return getattr(self._choices, data)

这与Tahir建议的解决方案类似,但更为简洁。

以下方法解决了此问题。我们可以为选项创建自定义字段

class ChoicesField(serializers.Field):
    def __init__(self, choices, **kwargs):
        self._choices = choices
        super(ChoicesField, self).__init__(**kwargs)

    def to_representation(self, obj):
        return self._choices[int(obj) - 1]  # obj is the first value

    def to_internal_value(self, data):
        return getattr(self._choices, data)
这与Tahir提出的解决方案类似,但更为清洁