我是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>
答案 0 :(得分:0)
而不是cleaned_data
在update
方法中使用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