簡體   English   中英

DRF - 帶有非模型 write_only 字段的 ModelSerializer

[英]DRF - ModelSerializer with a non-model write_only field

我有以下模型、序列化程序和視圖。 我的目標是傳遞一個自定義字符串,如

referrer = "pid=email&af_sub1=ui_1120&c=xyz"

在POST方法中(下面RegisterViewSet)然后到viewset/serializer使用這個信息填寫referral_campaign、referral_media和inviting_user

所以:1.referrer 是 write_only 字段 2.referrer 不是模型中的字段,但信息將用於填充模型中的字段

如何以 DRF 方式實現這一點?

模型

class User(AbstractUser):     
    first_name = models.CharField(max_length=100, null=True, blank=True)
    last_name = models.CharField(max_length=100, null=True, blank=True)

    # social/viral feature related fields
    referral_campaign = models.CharField(default="", max_length = 200, help_text="Campaign that led to the user signup")
    referral_media_source = models.CharField(default="", max_length = 200, help_text="Campaign that led to the user signup")
    inviting_user = models.ForeignKey('self', help_text="Inviting user", null=True, blank=True)

序列化器

class UserSerializer(serializers.ModelSerializer):

class Meta:
    model = User
    fields = ('first_name', 'last_name',)
    write_only_fields = ('first_name', 'last_name', 'referrer')     #how to use this 'referrer' field to populate the Model fields?
    read_only_fields = ('id',)

看法

class RegisterViewSet(generics.CreateAPIView):

    model = User
    serializer_class = UserSerializer
    permission_classes = [
        permissions.AllowAny
    ]

對於 DRF3,

class UserSerializer(serializers.ModelSerializer):
    referrer = serializers.CharField(max_length=300, allow_blank=True, write_only=True)
    
    class Meta:
        model = User
        fields = ('id', 'first_name', 'last_name', 'referrer')

    def validate(self, attrs):
        # do your stuff
        attrs.pop('referer', None)  # avoid sending it back to model creation
        return super().validate(attrs)

從這個這個答案

對於新人。 'write_only_fields' 在 DRF 3 中已被棄用。

'extra_kwargs' 是新方法。 請參閱: http : //www.django-rest-framework.org/topics/3.0-announcement/#the-extra_kwargs-option

例子:

class UserSerializer(serializers.HyperlinkedModelSerializer):
    ...
    class Meta:
        model = User
        ...

        # 'write_only_fields' has been deprecated:
        #     write_only_fields = ('password',)
        extra_kwargs = {
            'password': {'write_only': True}
        }

首先,您需要在序列化程序中定義此字段:

class UserSerializer(serializers.ModelSerializer):
    referrer = serializers.CharField(max_length=300, allow_blank=True)
    class Meta:
        model = User
        fields = ('id', 'first_name', 'last_name', 'referrer')
        write_only_fields = ('first_name', 'last_name', 'referrer')     #how to use this 'referrer' field to populate the Model fields?
        read_only_fields = ('id',)

(我不確定你是否需要 write_only_fields 中的“first_name”、“last_name”,因為這意味着你只會得到 ID 作為響應,但這取決於你的要求)

現在,您需要覆蓋序列化程序 restore_object 方法:

def restore_object(self, attrs, instance=None):
    referrer = attrs.pop('referrer')
    # parse referrer to referral_campaign, referral_media_source, inviting_user 
    ...
    instance = super(UserSerializer, self).restore_object(attrs, instance=instance)
    instance.referral_campaign = referral_campaign
    instance.referral_media_source = referral_media_source
    instance.inviting_user = inviting_user
    return instance

(此答案假設 DRF 2)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM