Django Rest Framework如何从多个模型创建序列化器

时间:2018-08-31 10:52:07

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

我需要扩展用户模型以添加地址,分数,更多user_types等内容。有两种可能的实现方式,扩展用户模型或创建一个新模型,该模型将通过{ {1}}。我决定使用新模型,因为它看起来更容易,并且在this堆栈溢出问题中推荐使用。但是,现在我无法创建没有嵌套配置文件字段的序列化程序,而该字段未记录,因为默认的rest_framwork文档生成器无法生成嵌套序列化程序的文档。

我的OneToOneField如下:

UserSerializer

此序列化器采用以下JSON格式:

class UserSerializer(serializers.ModelSerializer):
    # This creates a nested profile field
    profile = ProfileSerializer(required=True)

    def create(self, validated_data):
        profile_data = validated_data.pop('profile')
        user = User.objects.create_user(**validate_data)
        profile, created = Profile.objects.upodate_or_creeate(user=user, defaults=profile_data)
        return user

    class Meta:
        model = User
        fields = ('id', 'username', 'email', 'password', 'buckelists', 'profile')
        read_only_fields = ('id',)
        extra_kwargs = {'password':{'write_only': True}}

这看起来很奇怪,用{ 'name': ..., 'email': ..., 'password': ..., 'profile': { 'address': ..., 'score': ..., 'user_type': ..., 'achievements': ..., 'country': ..., 'trusted': ..., } 生成的文档显示如下:

rest_framework.documentation.include_docs_urls

因此,不清楚配置文件字段中应包含哪些内容。我想创建将接受以下格式的序列化器:

{
    'username': ...,
    'email': ...,
    'password': ...,
    'field': ...,
}

是否可以从头开始创建自定义序列化程序?或者至少可以为嵌套序列化程序生成文档。

PS:我使用python3.6和Django 2.1

编辑: 这是我的models.py的相关部分:

{
    'name': ...,
    'email': ...,
    'password': ...,
    'address': ...,
    'score': ...,
    'user_type': ...,
    'achievements': ...,
    'country': ...,
    'trusted': ...,
}

编辑:

Mohammad Ali的答案为GET解决了这个问题,但是我也想使用POST,UPDATE和PATCH方法。我发现我必须使用class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) trusted = models.BooleanField(default=False) address = models.CharField(max_length=100, default="") COUNTRIES = ( ('CZ', 'Czech Republic'), ('EN', 'England'), ) country = models.CharField(max_length=2, choices=COUNTRIES, default="CZ") score = models.BigIntegerField(default=0) achievements = models.ManyToManyField(Achievement, blank=True) USER_TYPES = ( ('N', 'Normal'), ('C', 'Contributor'), ('A', 'Admin'), ) user_type = models.CharField(max_length=1, choices=USER_TYPES, default='N') @receiver(post_save, sender=settings.AUTH_USER_MODEL) def create_auth_token(sender, instance=None, created=False, **kwargs): if created: Token.objects.create(user=instance) @receiver(post_save, sender=User) def create_user_profile(sender, instance, created=False, **kwargs): if created: profile, created = Profile.objects.get_or_create(user=instance) profile.save() 参数,但这与序列化程序有关,我不知道如何在没有配置文件字段的情况下引用配置文件。

2 个答案:

答案 0 :(得分:1)

放轻松,您可以仅在create函数中创建Profile obj。

class UserSerializer(serializers.ModelSerializer):

    trusted = serializers.BooleanField()
    address = serializers.CharField()

    class Meta:
        model = User
        fields = ('username', 'email', 'password', 'trusted', 'address',)

    def create(self, validated_data):
        user = User.objects.create(username=validated_data['username'], email=validated_data['email'])
        user.set_password(validated_data['password'])
        user.save()

        profile = Profile(user=user, trusted=validated_data['trusted'], address=validated_data['address']
        profile.save()
        return validated_data

这只是您的方案的简短实现。您可以填充故事。

答案 1 :(得分:-1)

请阅读有关序列化程序的文档:Django REST FRAMEWORK     -用户related_name

user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="user_profile") # models

class ProfileSerializer(serializers.ModelSerializer):
    user = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(), required=False)

     class Meta:
        model = Profile
        fields = '__all__'


class UserSerializer(serializers.ModelSerializer):
    user_profile = ProfileSerializer(required=True)

    class Meta:
        model = User
        fields = '__all__'