djangorestframework' PUT' /' PATCH'方法不起作用

时间:2018-04-26 00:29:07

标签: django django-rest-framework foreign-keys

我是DRF和FK的新手,并且一直在努力做一个' PUT' /' PATCH'对于一个应用程序,但到目前为止不成功。其余的CRUD操作工作正常。我认为有一个FK元素会导致这个特定操作出现问题。如何获得更新 - ' PUT' /' PATCH'功能在这里吗?非常感谢您的帮助 - 许多事先提前:)

以下是相关摘要 -

models.py

    from django.db import models

# Create your models here.


class House(models.Model):
    house = models.CharField(max_length=50)
    parent_house = models.ForeignKey('self', related_name='base_house',
                           blank=True, null=True, on_delete=models.CASCADE)
    attributes = models.ManyToManyField('HouseAttributes',
                                        through='HouseAttributesMapping')

    class Meta:
        db_table = 'sku'

    def __str__(self):
        return "%s" % self.sku


class HouseAttributes(models.Model):
    house_attribute = models.CharField(max_length=50, unique=True)

    class Meta:
        db_table = 'house_attributes'

    def __str__(self):
        return "%s" % self.house_attribute


class HouseAttributesMapping(models.Model):
    house = models.ForeignKey(House, on_delete=models.CASCADE)
    house_attribute = models.ForeignKey(HouseAttributes, on_delete=models.CASCADE)
    value = models.CharField(max_length=50)

    class Meta:
        db_table = 'house_attributes_mapping'

views.py

  

from .models import House, HouseAttributes, HouseAttributesMapping
from serializers.skuSerializer import HouseListSerializer, HouseDetailSerializer

from rest_framework import generics, mixins
from rest_framework import viewsets

# Create your views here.

class HouseListApi(mixins.ListModelMixin, mixins.CreateModelMixin,
                 generics.GenericAPIView):
    queryset = House.objects.all()
    serializer_class = HouseListSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)


class HouseDetailApi(generics.RetrieveUpdateDestroyAPIView):
    queryset = House.objects.all()
    serializer_class = HouseDetailSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)


class HouseViewSet(viewsets.ModelViewSet):
    """
    This viewset automatically provides `list`, `create`, `retrieve`,
    `update` and `destroy` actions.
    """
    queryset = House.objects.all()
    serializer_class = HouseListSerializer

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)

Serializers,我在那里进行了更改 - " def update"在CowDetailSerializer下

   from rest_framework import serializers
from apps.skus.models import House, HouseAttributes, HouseAttributesMapping

class HouseAttributesSerializer(serializers.ModelSerializer):
    class Meta:
        model = HouseAttributes
        fields = ("house_attribute",)


class HouseAttributesMappingSerializer(serializers.ModelSerializer):
    house_attribute = serializers.ReadOnlyField(
        source='house_attribute.sku_attribute')

    class Meta:
        model = HouseAttributesMapping

        fields = ('house_attribute', 'value')
        order_by = ('house_attribute')


class ParentHouseSerializer(serializers.ModelSerializer):
    parent_detail = serializers.HyperlinkedIdentityField(
        view_name='house_detail_api', lookup_field="pk")
    class Meta:
        model = House
        fields = ("id", "house", "parent_detail")


class HouseDetailSerializer(serializers.ModelSerializer):
    queryset = HouseAttributes.objects.all()
    house_attributes = HouseAttributesMappingSerializer(
        source='houseattributesmapping_set', many = True)
    class Meta:
        model = House
        depth = 1
        fields = ("house", "house_attributes")


    def update(self, validated_data, kwargs={}):
        house_value = self.data['house']
        house = {'house': house_value}
        houSe = House.objects.get_or_create(**self.data.house_attributes)

        return data


import ast

class HouseListSerializer(serializers.HyperlinkedModelSerializer):
    detail = serializers.HyperlinkedIdentityField(view_name='house_detail_api',
                                                  lookup_field="pk")

    parent_house = serializers.StringRelatedField()

    class Meta:
        model = House
        fields = ("house", "detail", "parent_house")

        def create(self, validated_data, kwargs={}):
            house_detail = self.objects.create(**validated_data)
            house = House.objects.get_or_create(house_detail)[0]['sku']

            return house

当我尝试使用上面引用的&#def;更新'更新用户界面上的表单时' CowDetailSerializer'下的代码,这是我得到的错误 - 我已经发布了完整的回溯,并在最后一行拉出了局部变量。

    AttributeError at /list/1/
'ReturnDict' object has no attribute 'sku_attributes'
Request Method: PUT
Request URL:    http://localhost:8000/list/1/
Django Version: 2.0.4
Exception Type: AttributeError
Exception Value:    
'ReturnDict' object has no attribute 'house_attributes'
Exception Location: /home/Downloads/transcend/serializers/houseSerializer.py in update, line 74
Python Executable:  /home/anaconda3/envs/transcend/bin/python
Python Version: 3.6.5
Python Path:    
['/home/Downloads/transcend',
 '/home/anaconda3/envs/transcend/lib/python36.zip',
 '/home/anaconda3/envs/transcend/lib/python3.6',
 '/home/anaconda3/envs/transcend/lib/python3.6/lib-dynload',
 '/home/anaconda3/envs/transcend/lib/python3.6/site-packages']
Server time:    Wed, 25 Apr 2018 21:08:40 +0000
Traceback Switch to copy-and-paste view
/home/anaconda3/envs/transcend/lib/python3.6/site-packages/django/core/handlers/exception.py in inner
            response = get_response(request) ...
▶ Local vars
/home/anaconda3/envs/transcend/lib/python3.6/site-packages/django/core/handlers/base.py in _get_response
                response = self.process_exception_by_middleware(e, request) ...
▶ Local vars
/home/anaconda3/envs/transcend/lib/python3.6/site-packages/django/core/handlers/base.py in _get_response
                response = wrapped_callback(request, *callback_args, **callback_kwargs) ...
▶ Local vars
/home/anaconda3/envs/transcend/lib/python3.6/site-packages/django/views/decorators/csrf.py in wrapped_view
        return view_func(*args, **kwargs) ...
▶ Local vars
/home/anaconda3/envs/transcend/lib/python3.6/site-packages/django/views/generic/base.py in view
            return self.dispatch(request, *args, **kwargs) ...
▶ Local vars
/home/anaconda3/envs/transcend/lib/python3.6/site-packages/rest_framework/views.py in dispatch
            response = self.handle_exception(exc) ...
▶ Local vars
/home/anaconda3/envs/transcend/lib/python3.6/site-packages/rest_framework/views.py in handle_exception
            self.raise_uncaught_exception(exc) ...
▶ Local vars
/home/anaconda3/envs/transcend/lib/python3.6/site-packages/rest_framework/views.py in dispatch
            response = handler(request, *args, **kwargs) ...
▶ Local vars
/home/Downloads/transcend/apps/skus/views.py in put
        return self.update(request, *args, **kwargs) ...
▶ Local vars
/home/anaconda3/envs/transcend/lib/python3.6/site-packages/rest_framework/mixins.py in update
        self.perform_update(serializer) ...
▶ Local vars
/home/anaconda3/envs/transcend/lib/python3.6/site-packages/rest_framework/mixins.py in perform_update
        serializer.save() ...
▶ Local vars
/home/anaconda3/envs/transcend/lib/python3.6/site-packages/rest_framework/serializers.py in save
            self.instance = self.update(self.instance, validated_data) ...
▶ Local vars
/home/Downloads/transcend/serializers/houseSerializer.py in update
        houSe = House.objects.get_or_create(**self.data.sku_attributes) ...
▼ Local vars
Variable    Value
kwargs  
{'house': 'CXA-03070-B110',
 'houseattributesmapping_set': [OrderedDict([('value',
                                            'CXccccccccccccccccccccccccccccccc3070H')]),
                              OrderedDict([('value', 'HIGH')]),
                              OrderedDict([('value', 'rbtsh8_6_3-nic1')]),
                              OrderedDict([('value', 'LDB')])]}
self    
HouseDetailSerializer(<House: CXA-03070-B110>, context={'request': <rest_framework.request.Request object>, 'format': None, 'view': <apps.house.views.houseDetailApi object>}, data={'house': 'CXA-03070-B110', 'house_attributes': [{'house_attribute': 'model', 'value': 'CXccccccccccccccccccccccccccccccc3070H'}, {'house_attribute': 'mclass', 'value': 'HIGH'}, {'house_attribute': 'preconfig', 'value': 'rbtsh8_6_3-nic1'}, {'house_attribute': 'serial_prefix', 'value': 'LDB'}]}, partial=False):
    house = CharField(max_length=50)
    house_attributes = HouseAttributesMappingSerializer(many=True, source='houseattributesmapping_set'):
        house_attribute = ReadOnlyField(source='house_attribute.house_attribute')
        value = CharField(max_length=50)
house   
{'house': 'CXA-03070-B110'}
house_value 
'CXA-03070-B110'
validated_data  
<House: CXA-03070-B110>

1 个答案:

答案 0 :(得分:0)

而不是cleaned_dataupdate方法中使用cleaned_data。此外,由于hous_attributes是dict,因此您应该get()通过.语法,而不是def update(self, validated_data, kwargs={}): house_value = validated_data['house'] house = {'house': house_value} houSe = House.objects.get_or_create(**validated_data.get('house_attributes')) return houSe 这样:

def integrate_tol(f, a, b, tol):
    N = 5
    old_integral = integrate(f, a, b, N)
    while True:
        N *= 2
        new_integral = integrate(f, a, b, N)
        if np.abs(old_integral - new_integral) < tol:
            return (4*new_integral - old_integral)/3
        old_integral = new_integral