Django rest framework serializer create 方法声称参数数量错误

Django rest framework serializer create method claims wrong number of arguments

我正在使用嵌套的 Django 序列化程序:

型号:

class Project(models.Model):
    # client = models.CharField(max_length=300)
    name = models.CharField(max_length=140)
    description = models.CharField(max_length=500)
    sold = models.BooleanField(default=False)


class Phase(models.Model):
    name = models.CharField(max_length=140)
    sold = models.BooleanField(default=False)
    project = models.ForeignKey(
        Project, on_delete=models.CASCADE, related_name="phases"
    )
    hourly_rate = models.IntegerField()


class Feature(models.Model):
    phase = models.ForeignKey(Phase, on_delete=models.CASCADE, related_name="features")
    name = models.CharField(max_length=140)
    description = models.CharField(max_length=500)
    hours = models.IntegerField()

序列化程序:

class FeatureSerializer(serializers.ModelSerializer):
    class Meta:
        model = Feature
        exclude = ["phase"]

class PhaseSerializer(serializers.ModelSerializer):
    features = FeatureSerializer(many=True)

    class Meta:
        model = Phase
        exclude = ["project"]
        depth = 3

    def create(self, validated_data):
        features_data = validated_data.pop("features")
        phase = Phase.objects.create(**validated_data)
        for feature_data in features_data:
            Feature.objects.create(phase=phase, **feature_data)
        return phase


class ProjectSerializer(serializers.ModelSerializer):
    phases = PhaseSerializer(many=True)

    class Meta:
        model = Project
        fields = "__all__"
        depth = 3

    def create(self, validated_data):
        phases_data = validated_data.pop("phases")
        project = Project.objects.create(**validated_data)
        for phase_data in phases_data:
            phase_data.update({"project": project})
            PhaseSerializer.create(phase_data)
        return project

出于某种原因调用 PhaseSerializer.create 方法会抱怨 create() missing 1 required positional argument: 'validated_data'。我不明白这是怎么回事,因为它是用一个参数调用的(绝对不是 null...)

完整追溯:

Environment:


Request Method: POST
Request URL: http://localhost:8092/projects/projects/

Django Version: 2.1.7
Python Version: 3.7.2
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'rest_framework',
 'projects']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/Users/foobar/.pyenv/versions/management/lib/python3.7/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/Users/foobar/.pyenv/versions/management/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)

File "/Users/foobar/.pyenv/versions/management/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/Users/foobar/.pyenv/versions/management/lib/python3.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
  54.         return view_func(*args, **kwargs)

File "/Users/foobar/.pyenv/versions/management/lib/python3.7/site-packages/rest_framework/viewsets.py" in view
  116.             return self.dispatch(request, *args, **kwargs)

File "/Users/foobar/.pyenv/versions/management/lib/python3.7/site-packages/rest_framework/views.py" in dispatch
  495.             response = self.handle_exception(exc)

File "/Users/foobar/.pyenv/versions/management/lib/python3.7/site-packages/rest_framework/views.py" in handle_exception
  455.             self.raise_uncaught_exception(exc)

File "/Users/foobar/.pyenv/versions/management/lib/python3.7/site-packages/rest_framework/views.py" in dispatch
  492.             response = handler(request, *args, **kwargs)

File "/Users/foobar/.pyenv/versions/management/lib/python3.7/site-packages/rest_framework/mixins.py" in create
  21.         self.perform_create(serializer)

File "/Users/foobar/.pyenv/versions/management/lib/python3.7/site-packages/rest_framework/mixins.py" in perform_create
  26.         serializer.save()

File "/Users/foobar/.pyenv/versions/management/lib/python3.7/site-packages/rest_framework/serializers.py" in save
  214.             self.instance = self.create(validated_data)

File "/Users/foobar/work/sva/management/projects/serializers.py" in create
  40.             PhaseSerializer.create(phase_data)

Exception Type: TypeError at /projects/projects/
Exception Value: create() missing 1 required positional argument: 'validated_data'

试试这个

class ProjectSerializer(serializers.ModelSerializer):
    phases = PhaseSerializer(many=True)

    class Meta:
        model = Project
        fields = "__all__"
        depth = 3

    def create(self, validated_data):
        phases_data = validated_data.pop("phases")
        project = Project.objects.create(**validated_data)
        for phase_data in phases_data:
            phase_data.update({"project": project})
            
            <b>phase_data.pop("features",None)</b>
            <b>Phase.objects.create(**phase_data)</b>
            <b><strike>PhaseSerializer.create(phase_data)</strike> # remove this</b>

        return project

更新

如下更改您的serializers.py

class FeatureSerializer(serializers.ModelSerializer):
    class Meta:
        model = Feature
        exclude = ["phase"]


class PhaseSerializer(serializers.ModelSerializer):
    features = FeatureSerializer(many=True)

    class Meta:
        model = Phase
        exclude = ["project"]
        depth = 3
    <b># remove this "create()" method, it's not relevent here</b>
    <strike># def create(self, validated_data):
    #     features_data = validated_data.pop("features")
    #     phase = Phase.objects.create(**validated_data)
    #     for feature_data in features_data:
    #         Feature.objects.create(phase=phase, **feature_data)
    #     return phase</strike>


class ProjectSerializer(serializers.ModelSerializer):
    phases = PhaseSerializer(many=True)

    class Meta:
        model = Project
        fields = "__all__"
        depth = 3

    <b>def create(self, validated_data):
        phases_data = validated_data.pop("phases")
        project_instance = Project.objects.create(**validated_data)
        for phase_data in phases_data:
            features = phase_data.pop("features", None)
            phase_data.update({"project": project_instance})
            phase_instance = Phase.objects.create(**phase_data)
            for feature in features:
                feature.update({"phase": phase_instance})
                Feature.objects.create(**feature)
        return project_instance</b>