python - DRY 调用 serializer.data 不会返回模型的更新实例

标签 python django django-rest-framework django-serializer

我正在研究 BlogSerializer 的更新部分。当我调用 blog_serializer.data 时,传递给序列化器的实例会在数据库中更新,返回旧数据而不是新数据,但当我刷新浏览器时,将显示最新数据。我已经检查过更新时没有错误。 那么如何才能在我的可浏览 API 中显示最新更新的数据

序列化器.py

class UserSerializer(ModelSerializer):

    class Meta:
        model = User
        fields = '__all__'


class BlogFilesSerializer(ModelSerializer):
    created_at = serializers.SerializerMethodField()
    updated_at = serializers.SerializerMethodField()

    class Meta:
        model = BlogFilesModel
        fields = ('blog_files_id', 'blog', 'path',
                  'created_at', 'updated_at')
        extra_kwargs = {
            'path': {
                'error_messages': {
                    'blank': 'File is required'
                },
            },
            'blog' : {
                'error_messages': {
                    'blank': 'blog must be selected'
                },
            }
        }

    def get_created_at(self, obj):
        formatted_date = obj.created_at.strftime("%d-%m-%Y")
        return formatted_date

    def get_updated_at(self, obj):
        formatted_date = obj.created_at.strftime("%d-%m-%Y")
        return formatted_date


class BlogSerializer(ModelSerializer):
    blog_files = serializers.SerializerMethodField()
    uploaded_files = serializers.FileField(write_only=True, required=True)
    blog_created_at = serializers.SerializerMethodField(read_only=False)

    class Meta:
        model = BlogModel
        fields = ('blog_id', 'user', 'title', 'content',
                  'status', 'blog_files', 'blog_created_at',
                  'uploaded_files',
                  )
        extra_kwargs = {
            'title': {
                'error_messages': {
                    'blank': 'Title field must not be left blank..'
                },
                'label': 'Enter Blog Title',
                'help_text': 'This is help text of title field'
            }
        }

    def __init__(self, *args, **kwargs):

        set_read_only_fields = kwargs.pop('set_read_only_fields', None)
        if set_read_only_fields:
            for field_name in set_read_only_fields:
                if self.fields.get(field_name):
                    if hasattr(self.fields[field_name], 'allow_empty_file'):

                        self.fields[field_name].allow_empty_file = True
                        self.fields[field_name].required = False

        set_remove_fields = kwargs.pop('set_remove_fields', None)
        super(BlogSerializer, self).__init__(*args, **kwargs)

        if set_remove_fields:
            for field_name in set_remove_fields:
                self.fields.pop(field_name)

    def create(self, validated_data):
        files = validated_data.pop('uploaded_files')
        instance = BlogModel.objects.create(**validated_data)

        file_list = self.context.get(
            'view').request.FILES.getlist('uploaded_files')

        info = []
        for i in file_list:
            row = {
                'blog': instance.blog_id,
                'path': i
            }
            info.append(row)

        if len(info) > 0:
            file_instance = BlogFilesSerializer(data=info, many=True)

            if file_instance.is_valid():
                file_instance.save()
        return instance

    def update(self, instance, validated_data):

        file_list = validated_data.pop('uploaded_files', None)

        instance.title = validated_data.get('title', instance.title)
        instance.content = validated_data.get('content', instance.content)
        instance.user = validated_data.get('user', instance.user)
        instance.status = validated_data.get('status', instance.status)
        instance.save()

        if not isinstance(file_list, (list)):
            file_list =  [file_list]

        info = []
        for i in file_list:
            row = {
                'blog': instance.blog_id,
                'path': i
            }
            info.append(row)

        if len(info) > 0:
            file_instance = BlogFilesSerializer(data=info, many=True)
            if file_instance.is_valid():
                file_instance.save()
        return instance

    def get_blog_files(self, obj):
        info = BlogFilesSerializer(BlogFilesModel.objects.filter(
            blog=obj).order_by('-pk'), many=True)

        if info.data:
            for i in info.data:
                user_detail = User.objects.get(pk=obj.user.id)
                i.__setitem__('user_detail', UserSerializer(user_detail).data)
                if i.get('user_detail'):
                    try:
                        del i['user_detail']['password']
                    except expression as identifier:
                        pass

        return info.data

    def get_blog_created_at(self, obj):
        formatted_date = obj.created_at.strftime("%d-%m-%Y")
        return formatted_date

View .py

class BlogViewSet(viewsets.ModelViewSet):
    queryset = BlogModel.objects.all()
    lookup_field = 'blog_id'
    serializer_class = BlogSerializer
    parser_classes = (MultiPartParser, FormParser, FileUploadParser)

    def update(self, request, *args, **kwargs):
        info = {'msg':'something went wrong'};
        partial = kwargs.pop('partial', False)
        instance = BlogModel.objects.get(pk=kwargs['blog_id'])
        blog_serializer = BlogSerializer(instance,data=request.data,set_read_only_fields=['uploaded_files'],partial=True) 
        is_valid = blog_serializer.is_valid()
        if is_valid:
            blog_serializer.save()
            return Response(blog_serializer.data) #here i'm getting previous old data insisted on latest one
        else:
            return Response(blog_serializer.errors,
                            status=status.HTTP_400_BAD_REQUEST)

编辑1)在serializer.py部分添加更多内容

希望我已经为我的问题提供了足够的详细信息

最佳答案

如何将 return Response(blog serializer.data) 更改为 return Response(blog serializer.validated_data)

关于python - DRY 调用 serializer.data 不会返回模型的更新实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55662858/

相关文章:

python - django admin禁用特定用户的密码更改

Django 将两个值序列化/反序列化到一个模型字段

具有静态方法和对自身的引用的 Python 类

Django休息框架: How to set a field to null via PATCH request?

Python:生成二维点/簇

Python 和变量传递

python - Django 音频文件表单验证

python - Pandas : dropping multiple columns and keeping only ones with numeric data

python - 减去数据框的最佳方法

python - 在同一个 apache 服务器上运行 django 和 flask