Thanks to visit codestin.com
Credit goes to github.com

Skip to content

ModelSerializer generate ChoicesField will discard default parameter #7469

Closed
@sankforever

Description

@sankforever

model

class Brand(models.Model):
    name = models.CharField(_("名称"), max_length=50, unique=True)
    status = models.SmallIntegerField(
        verbose_name=_("状态"),
        choices=BrandStatus.choices,
        default=BrandStatus.ENABLE.value,
        help_text=make_markdown_table(BrandStatus.choices)
    )
    description = models.CharField(
        _("描述"), max_length=300, null=True, blank=True
    )
    creator = models.ForeignKey(
        "users.User", on_delete=models.CASCADE, verbose_name=_("拥有者")
    )
    created = models.DateTimeField(_("创建时间"), auto_now_add=True)
    updated = models.DateTimeField(_("更新时间"), auto_now=True)

Serializer

class BrandSerializer(serializers.ModelSerializer):
    name = serializers.CharField(max_length=50, validators=[special_character])
    created = serializers.DateTimeField(read_only=True)
    updated = serializers.DateTimeField(read_only=True)
    creator = serializers.ReadOnlyField(source="creator.username")

    class Meta:
        model = Brand
        fields = "__all__"

swagger
swagger

So i find

Serializers.ModelSerializer

if 'choices' in field_kwargs:
  # Fields with choices get coerced into `ChoiceField`
  # instead of using their regular typed field.
  field_class = self.serializer_choice_field
  # Some model fields may introduce kwargs that would not be valid
  # for the choice field. We need to strip these out.
  # Eg. models.DecimalField(max_digits=3, decimal_places=1, choices=DECIMAL_CHOICES)
  valid_kwargs = {
    'read_only', 'write_only',
    'required', 'default', 'initial', 'source',
    'label', 'help_text', 'style',
    'error_messages', 'validators', 'allow_null', 'allow_blank',
    'choices'
  }
  for key in list(field_kwargs):
    if key not in valid_kwargs:
      field_kwargs.pop(key)

default parameter not in valid_kwargs and will pop, but default in field_kwargs['field_kwargs']

I rewrite

class ModelSerializer(serializers.ModelSerializer):
    def build_standard_field(self, field_name, model_field):
        field_kwargs = get_field_kwargs(field_name, model_field)
        if 'choices' in field_kwargs:
            # Fields with choices get coerced into `ChoiceField`
            # instead of using their regular typed field.
            field_class = self.serializer_choice_field
            # Some model fields may introduce kwargs that would not be valid
            # for the choice field. We need to strip these out.
            # Eg. models.DecimalField(max_digits=3, decimal_places=1, choices=DECIMAL_CHOICES)
            valid_kwargs = {
                'read_only', 'write_only',
                'required', 'default', 'initial', 'source',
                'label', 'help_text', 'style',
                'error_messages', 'validators', 'allow_null', 'allow_blank',
                'choices'
            }
            field_kwargs["default"] = field_kwargs["model_field"].default  # add this
            for key in list(field_kwargs):
                if key not in valid_kwargs:
                    field_kwargs.pop(key)
        else:
            field_class, field_kwargs = super(ModelSerializer, self).build_standard_field(field_name, model_field)
        return field_class, field_kwargs

swagger
swager2

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions