使用来自validated_data的kwargs的Django Rest Framework update()

时间:2018-12-14 12:23:55

标签: python django django-rest-framework

是否可以在不指定所有实例字段的情况下一行更新实例?

例如:

def update(self, instance, validated_data):
    instance.name = validated_data.get('name', instance.name)
    instance.address = validated_data.get('address', instance.address)
    instance.save()
    return instance

因此,想象一下在名称和地址旁边是否还有更多字段。 我可以做些什么从validated_data中提取kwarg吗?就像在create()方法中一样:

def create(self, validated_data):
    return Person.objects.create(**validated_data)

2 个答案:

答案 0 :(得分:4)

它不是单线的,但足够短(extracted from the drf sources):

"name":"Help Us Grow our Fleet with a Go Bananas Food Trailer","blurb":"We are ready to take our business to the next level by adding a Go Bananas Food Trailer to our fleet to operate in MN and AZ.","goal":12000.0,"pledged":0.0,"state":"live","slug":"help-us-grow-our-fleet-with-a-go-bananas-food-trai","disable_communication":false,"country":"US","currency":"USD","currency_symbol":"$","currency_trailing_code":true,"deadline":1549975076,"state_changed_at":1544791076,"created_at":1544049789,"launched_at":1544791076,"staff_pick":false,"is_starrable":true,"backers_count":0,"static_usd_rate":1.0,"usd_pledged":"0.0","converted_pledged_amount":0,"fx_rate":1.0,"current_currency":"USD","usd_type":"international","creator":{"id":469256311,"name":"Lisa Bastien","slug":"gobananas","is_registered":null,"chosen_currency":null,"avatar":{"thumb":"https://ksr-ugc.imgix.net/assets/023/484/870/b425950910db87fbf3db68cf6af0ba32_original.jpg?ixlib=rb-1.1.0&w=40&h=40&fit=crop&v=1544055848&auto=format&frame=1&q=92&s=f6df473d01d0ae8e957ef915fc57d089","small":"https://ksr-ugc.imgix.net/assets/023/484/870/b425950910db87fbf3db68cf6af0ba32_original.jpg?ixlib=rb-1.1.0&w=160&h=160&fit=crop&v=1544055848&auto=format&frame=1&q=92&s=4c560ceb28103abb9aa977df12c0e43d","medium":"https://ksr-ugc.imgix.net/assets/023/484/870/b425950910db87fbf3db68cf6af0ba32_original.jpg?ixlib=rb-1.1.0&w=160&h=160&fit=crop&v=1544055848&auto=format&frame=1&q=92&s=4c560ceb28103abb9aa977df12c0e43d"},"urls":{"web":{"user":"https://www.kickstarter.com/profile/gobananas"},"api":{"user":"https://api.kickstarter.com/v1/users/469256311?signature=1544879587.06bd700b38861ad1b10b98000d2029cdb52fd839"}}},"location":{"id":2487129,"name":"St. Paul","slug":"st-paul-mn","short_name":"St. Paul, MN","displayable_name":"St. Paul, MN","localized_name":"St. Paul","country":"US","state":"MN","type":"Town","is_root":false,"urls":{"web":{"discover":"https://www.kickstarter.com/discover/places/st-paul-mn","location":"https://www.kickstarter.com/locations/st-paul-mn"},"api":{"nearby_projects":"https://api.kickstarter.com/v1/discover?signature=1544866329.8e94c3149b792ab1670a78bcc28d58b8acb9e302&woe_id=2487129"}}},"category":{"id":311,"name":"Food Trucks","slug":"food/food trucks","position":8,"parent_id":10,"color":16725570,"urls":{"web":{"discover":"http://www.kickstarter.com/discover/categories/food/food%20trucks"}}},"profile":{"id":3529735,"project_id":3529735,"state":"inactive","state_changed_at":1544049789,"name":null,"blurb":null,"background_color":null,"text_color":null,"link_background_color":null,"link_text_color":null,"link_text":null,"link_url":null,"show_feature_image":false,"background_image_opacity":0.8,"should_show_feature_image_section":true,"feature_image_attributes":{"image_urls":{"default":"https://ksr-ugc.imgix.net/assets/023/483/978/b425950910db87fbf3db68cf6af0ba32_original.jpg?ixlib=rb-1.1.0&crop=faces&w=1552&h=873&fit=crop&v=1544050003&auto=format&frame=1&q=92&s=5593a7650dbff908681a5d42abcaee51","baseball_card":"https://ksr-ugc.imgix.net/assets/023/483/978/b425950910db87fbf3db68cf6af0ba32_original.jpg?ixlib=rb-1.1.0&crop=faces&w=560&h=315&fit=crop&v=1544050003&auto=format&frame=1&q=92&s=1460cab50f8a4968d759ec34d1cf91d5"}}},"spotlight":false,"urls":{"web":{"project":"https://www.kickstarter.com/projects/gobananas/help-us-grow-our-fleet-with-a-go-bananas-food-trai?ref=newest","rewards":"https://www.kickstarter.com/projects/gobananas/help-us-grow-our-fleet-with-a-go-bananas-food-trai/rewards"}}}

答案 1 :(得分:0)

尝试使用以下PUT功能。根据REST HTTP方法标准,PUT更合适。

def put(self, request, validated_data, *args, **kwargs):

    try:
        instance = self.queryset.get(pk=kwargs['pk'])
        serializer = InstanceSerializer()
        updated_instance = serializer.update(instance, request.data)
        return Response(InstanceSerializer(updated_instance).data)
    except Instance.DoesNotExist:
        return Response(
            data={
                'message': 'instance does not exist'
            },
            status=status.HTTP_404_NOT_FOUND
        )

首先,根据其pk获取实例。添加serializer以稍后序列化数据。然后使用序列化器获取要更新的数据,最后将其添加到响应中(如果需要更新的数据)。