【问题标题】:Exclude some fields while posting to Django Rest Framework发布到 Django Rest Framework 时排除某些字段
【发布时间】:2017-02-12 08:15:01
【问题描述】:

我的 DRF 中保存了以下字段。

  1. 生物
  2. 网站
  3. 电话机
  4. 性别
  5. 头像

我使用 react-native 作为前端。在更新用户配置文件时,我只想将更改发布到服务器。但是在发布到其余 api 时,有必要在 formData 中发布所有值,包括头像,并且由于头像没有改变,我试图通过现有的服务器上的 uri 似乎不起作用。 我尝试创建另一个序列化程序并使用 PUT 将数据传递给服务器,但它也不起作用。我不断收到错误消息。

"detail": "Multipart form parse error - Invalid boundary in multipart: None"

我认为这可能是因为传递的 uri 无效。我也尝试在序列化程序中使用 get_validation_exclusions() 方法,但它也不起作用。如何在更新所有其他已更改的字段时使头像的发布成为可选?

views.py

class ProfileView(APIView):
serializer_class = ProfileSerializer
def get(self, request, format=None):
    snippets = Profile.objects.filter(pk=request.user.id)
    serializer = ProfileSerializer(snippets, many=True)
    return Response(serializer.data)

def post(self, request, format=None):
    serializer = ProfileSerializer(data=request.data)
    if serializer.is_valid():
        user= User.objects.get(pk=request.user.id)
        user.profile.bio=request.data["bio"]
        user.profile.website=request.data["website"]
        user.profile.gender=request.data["gender"]
        user.profile.phoneno=request.data["phoneno"]
        user.profile.avatar=request.data["avatar"]
        user.profile.save()
        user.save()
        return Response(serializer.data,status=status.HTTP_201_CREATED)
    else:
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

def put(self, request, format=None):
    snippet = User.objects.filter(pk=request.user.id)
    serializer = ChangeProfileSeralizer(snippet, data=request.data)
    if serializer.is_valid():
        user= User.objects.get(pk=request.user.id)
        user.profile.bio=request.data["bio"]
        user.profile.website=request.data["website"]
        user.profile.gender=request.data["gender"]
        user.profile.phoneno=request.data["phoneno"]
        user.profile.save()
        return Response(serializer.data, status=status.HTTP_200_OK)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

序列化器.py

class ChangeProfileSeralizer(serializers.HyperlinkedModelSerializer):
    class Meta:
       model = Profile
       fields = ('website', 'phoneno','gender','bio')

class ProfileSerializer(serializers.HyperlinkedModelSerializer): 
    avatar=serializers.ImageField(max_length=None,use_url=True)
    website = serializers.CharField(required=False)
    phoneno = serializers.CharField(required=False)
    gender = serializers.CharField(required=False)
    avatar = serializers.ImageField(required=False)

    class Meta:
        model = Profile
        fields = ('bio','website','phoneno','gender','avatar')

    def get_validation_exclusions(self,instance=None):
        exclusions = super(ProfileSerializer, self).get_validation_exclusions(instance)
        return exclusions +['avatar']

编辑(配置文件模型):

class Profile(models.Model):
   user = models.OneToOneField(User, on_delete=models.CASCADE,primary_key=True)
   bio = models.TextField(max_length=500, blank=True)
   website = models.TextField(max_length=200, blank=True)
   phoneno = models.TextField(max_length=200, blank=True)
   gender = models.TextField(max_length=200, blank=True)
   avatar = models.ImageField('profile picture', upload_to='images/avatar/', default='/images/avatar/blank.png')

【问题讨论】:

  • 你有没有试过在序列化器的头像ImageField上设置required=False,然后在发布请求时只排除该字段?

标签: python django-rest-framework


【解决方案1】:

如果您希望 Avatar 字段为只读,您有两个选择。

选项 1

您可以确保 ImageField 不是 @Ruben 所说的那样

class ProfileSerializer(serializers.HyperlinkedModelSerializer):
    avatar = serializers.ImageField(required=False)

选项 2

如果该字段存储图像的字符串表示,并且您计划在前端对其进行解析,那么您可以简单地将头像设为ReadOnlyField

class ProfileSerializer(serializers.HyperlinkedModelSerializer): 
    avatar = serializers.ReadOnlyField()

    class Meta:
        model = Profile
        fields = '__all__'

【讨论】:

    【解决方案2】:

    如果您使用的是 Django 中的模型,那么您需要进行更改

    序列化器.py

    class ProfileSerializer(serializers.ModelSerializer): 
    
            class Meta:
                model = Profile
                exclude = ('user',)
    

    views.py

    class ProfileView(views.ModelViewSet):
        serializer_class = ProfileSerializer
        queryset = Profile.objects.all()
    

    urls.py

    router = DefaultRouter()
    router.register(r'profile', ProfileView)
    

    现在您可以直接访问您的模型

    它的工作原理你可以看这里:

    Model Serializer in DRF;

    Model Viewset;

    Default router

    【讨论】:

    • 没有工作最终给出了同样的错误。 { "detail": "Multipart form parse error - Invalid boundary in multipart: None" } 你认为可能是什么问题?
    • 您从哪里获得 Profile 模型?
    • 这是一个与 Django 用户模型相关联的一对一字段。我已将其添加到问题中,请查看...
    • 这行不通。 DRF 不允许您同时指定 fieldsexclude
    猜你喜欢
    • 1970-01-01
    • 2019-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-17
    • 1970-01-01
    • 2016-02-12
    • 2019-07-20
    相关资源
    最近更新 更多