【问题标题】:How to display all model fields with ModelSerializer?如何使用 ModelSerializer 显示所有模型字段?
【发布时间】:2015-07-28 06:27:02
【问题描述】:

models.py

class Car():
    producer = models.ForeignKey(Producer, blank=True, null=True,)
    color = models.CharField()
    car_model = models.CharField()
    doors = models.CharField()

serializers.py

class CarSerializer(ModelSerializer):

    class Meta:
        model = Car
        fields = Car._meta.get_all_field_names()

所以,我想在这里使用所有字段。但我有一个错误:

字段名称producer_id 对模型Car 无效。

如何解决这个问题?

谢谢!

【问题讨论】:

  • 能否在您的问题中包含此错误的回溯?

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


【解决方案1】:

根据Django REST Framework's Documentation on ModelSerializers

默认情况下,类上的所有模型字段都会映射到对应的序列化器字段。

这与Django's ModelForms 不同,后者需要您specify the special attribute '__all__' 才能使用所有模型字段。因此,只需声明模型即可。

class CarSerializer(ModelSerializer):
    class Meta:
        model = Car

更新(版本 >= 3.5)

上述行为在 3.3 版中已被弃用,自 3.5 版起被禁止。

It is now mandatory 使用特殊属性 '__all__' 使用 Django REST Framework 中的所有字段,与 Django Forms 相同:

未能设置字段或排除在 3.3 版中引发了待决弃用警告,并在 3.4 中引发了弃用警告。它现在是强制性的。

所以现在它必须是:

class CarSerializer(ModelSerializer):
    class Meta:
        model = Car
        fields = '__all__'

【讨论】:

  • 如何在模型的所有字段中再增加1个字段?
  • @Anuj `fields = (*[f.name for f in MyModel._meta.get_fields()], "another_field")
【解决方案2】:

您可以使用fields = '__all__' 获取所有字段,或者您可以指定是否要返回有限数量的字段。见documentation

但这会返回外键字段的 id 值,即在您的情况下为 producer。要获取producer 的所有字段,您还需要为此创建一个序列化程序类。见here

所以您更新后的 serializers.py 应该是:

class ProducerSerializer(ModelSerializer):
    class Meta:
        model = Producer

class CarSerializer(ModelSerializer):
    producer= ProducerSerializer(read_only=True)

    class Meta:
        model = Car
        fields = ('producer', 'color', 'car_model', 'doors', )

【讨论】:

    【解决方案3】:

    如果您希望所有字段都包含在序列化程序中,您可以使用 fields ='_ all _'

    class CarSerializer(serializer.ModelSerializer):
          class Meta:
               fields = '__all__'
               model = Car
    

    但不推荐这种方法。我们应该始终明确指定所有字段。这是因为它使我们能够控制显示的字段。如果我们不想显示字段数据,我们可以避免这种情况。

     class CarSerializer(serializer.ModelSerializer):
              class Meta:
                   fields = ['name','color','company','price']
                   model = Car
    

    【讨论】:

      猜你喜欢
      • 2017-07-24
      • 2015-04-04
      • 2012-05-19
      • 2020-02-14
      • 1970-01-01
      • 1970-01-01
      • 2021-04-11
      • 2023-03-21
      • 1970-01-01
      相关资源
      最近更新 更多