【问题标题】:Why do I get "AssertionError: May not set both `read_only` and `required`" in Django Rest Framework?为什么在 Django Rest Framework 中出现“AssertionError:可能无法同时设置 `read_only` 和 `required`”?
【发布时间】:2020-09-02 00:45:57
【问题描述】:

当我尝试访问 TestViewSet 时,为什么会收到 AssertionError: May not set both 'read_only' and 'required'

这里是 MRE:

models.py:

class Channel(models.Model):
    id = models.CharField(max_length=12, primary_key=True)

class Test(models.Model):
    channel = models.ForeignKey(Channel, on_delete=models.PROTECT)
    foo = models.IntegerField(default=1)

    class Meta:
        unique_together = (
            ('channel_id', 'foo'),
        )

views.py:

from rest_framework import routers, viewsets, serializers

class TestSerializer(serializers.ModelSerializer):
    class Meta:
        model = Test
        fields = [
            'channel_id',
            'foo',
        ]

class TestViewSet(viewsets.ModelViewSet):
    queryset = Test.objects.all()
    serializer_class = TestSerializer

router = routers.DefaultRouter()
router.register('test', TestViewSet)

如果您移除Test 上的唯一约束,或在序列化程序上设置fields='__all__',视图会神奇地再次开始工作。

我不想使用fields='__all__' 有两个原因:

  • 这会导致我的真实序列化器上出现大量未使用的数据
  • channel_id 列最终呈现为channel,这很不方便,并且将迫使我更新我的前端代码以引用channel,否则我将不得不将_id 附加到数据中。

我只想在序列化器上创建一个别名:

class TestSerializer(serializers.ModelSerializer):
    channel_id = serializers.CharField(source='channel_id')
    
    ...

但是这样做会导致另一个错误...

AssertionError: It is redundant to specify `source='channel_id'` on field 'CharField' in serializer 
'OrderSerializer', because it is the same as the field name. Remove the `source` keyword argument.

TLDR;

如何将channel 外键呈现为channel_id

【问题讨论】:

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


    【解决方案1】:

    明确声明channel_id

    class TestSerializer(serializers.ModelSerializer):
        channel_id = serializers.IntegerField()
    
        class Meta:
            model = Test
            fields = ['channel_id', 'foo', ]

    如果您希望将channel_id 的返回类型更改为字符串,则可以使用serializers.CharField 代替serializers.IntegerField

    【讨论】:

    • 从技术上讲,它应该是 IntegerField(),因为 FK 不会将它们的值存储为字符串 @Elrond 支持 Monica
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多