DRF将OneToOneField设置为当前登录的用户

时间:2019-03-05 13:15:47

标签: django django-rest-framework

我有一个具有这样的OneToOneField的模型:

android:adjustViewBounds="true"
android:scaleType="fitXY"

其序列化器如下所示:

class Customer(models.Model):
    """A Class to represent a Customer in  System """

    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)

现在可浏览的api显示了用户的下拉列表

Android ImageButton crops on resize

如何设置class CustomerSerializer(serializers.ModelSerializer): """A Serizlier class for customer """ class Meta: model = models.Customer fields = ('user', 'first_name', 'last_name', 'dob', 'gender') user中当前登录的用户并将其设置为只读?也就是说,该字段不应是端点的可传递参数,而应是与当前登录用户相对应的只读字段。

3 个答案:

答案 0 :(得分:2)

首先,应将 user 设置为read_only字段。这样,您 无法更改API中的值 。可以通过在字段中指定 read_only=True 来完成,也可以通过在序列化器的Meta类中添加read_only_fields来完成。

class CustomerSerializer(serializers.ModelSerializer):
    """A Serizlier class for customer """

    class Meta:
        model = models.Customer
        fields = ('user', 'first_name', 'last_name', 'dob', 'gender')
        read_only_fields = ('user',)


因此,DRF将不接受您正在发布的JSON有效负载对user字段的任何输入。


然后,如何在创建Customer实例时传递登录的用户值?

我假设您正在使用 ModelViewset 视图,这样它将把request对象和view对象传递给相应的序列化程序。在序列化程序中,我们可以通过序列化程序的 context 类变量访问上下文数据
因此,按如下所示覆盖 create() CustomerSerializer 方法(我将添加序列化器的完整配置)

class CustomerSerializer(serializers.ModelSerializer):
    """A Serizlier class for customer """

    class Meta:
        model = models.Customer
        fields = ('user', 'first_name', 'last_name', 'dob', 'gender')
        read_only_fields = ('user',) # added <<<<

    def create(self, validated_data): # override this method <<<
        """
        Since the 'user' is a read_only field, the validated data doesn't contain it.
        """
        user = self.context['request'].user
        validated_data['user'] = user
        return super().create(validated_data)

答案 1 :(得分:0)

我会限制视图集中的选择。

class MyViewset(ViewSet):
    serializer_class = CustomerSerializer
    def get_queryset(self):
        return Customer.objects.filter(user=self.request.user)

答案 2 :(得分:0)

您可以通过覆盖 CustomerSerializer get_fields(self)来实现。 传递当前请求用户和过滤器用户查询

class CustomerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Customer
        fields = ['user', 'first_name', 'last_name']

    def get_fields(self):
        fields = super().get_fields()
        current_user = self.context['request'].user
        fields['user'] = serializers.PrimaryKeyRelatedField(queryset=User.objects.filter(id=current_user.id))
        return fields