Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django Rest框架可写嵌套序列化程序引发AttributeError_Python_Django_Django Rest Framework - Fatal编程技术网

Python Django Rest框架可写嵌套序列化程序引发AttributeError

Python Django Rest框架可写嵌套序列化程序引发AttributeError,python,django,django-rest-framework,Python,Django,Django Rest Framework,我正在开发一个基于Django的装运管理应用程序。我们集成了Django Rest框架,并公开了几个端点 现在名为“port_manager”的django应用程序有以下几种型号 型号.py from location.models import CountryList, DistrictList class PortList(models.Model): name = models.CharField(max_length=45) countryList_id = model

我正在开发一个基于Django的装运管理应用程序。我们集成了Django Rest框架,并公开了几个端点

现在名为“port_manager”的django应用程序有以下几种型号

型号.py

from location.models import CountryList, DistrictList

class PortList(models.Model):
    name = models.CharField(max_length=45)
    countryList_id = models.ForeignKey(CountryList, models.SET_NULL, blank=True, null=True, verbose_name='related country')
    iso_code = models.CharField(max_length=10)
    short_code = models.CharField(max_length=10, null=True, blank=True)
    status = models.BooleanField(default=True)

    def __str__(self):
        return self.name

class PortDetail(models.Model):
    port = models.OneToOneField(PortList, models.CASCADE, verbose_name='related port', primary_key=True)
    phone = models.CharField(max_length=15)
    district_list_id = models.ForeignKey(DistrictList, models.SET_NULL, blank=True, null=True,
                                         verbose_name='related district')
    email = models.EmailField()
    fax = models.CharField(max_length=100, null=True, blank=True)
    address = models.TextField()
    map_location = models.CharField(max_length=45, null=True, blank=True)
    other_information = models.TextField(null=True, blank=True)
    current_pricing = models.IntegerField(null=True, blank=True)

    def __str__(self):
        return self.port.name+' Details'
from rest_framework import serializers
from port_manager.models import PortList, PortDetail
from location.models import CountryList, DistrictList

class PortListSerializer(serializers.ModelSerializer):
    countryList_id = serializers.PrimaryKeyRelatedField(queryset=CountryList.objects.all(), write_only=True)
    class Meta:
        model = PortList
        fields = ('name', 'countryList_id', 'iso_code')

class PortDetailSerializer(serializers.ModelSerializer):
    district_list_id = serializers.PrimaryKeyRelatedField(queryset=DistrictList.objects.all(),)
    class Meta:
        model = PortDetail
        fields = ('port', 'phone', 'district_list_id', 'email', 'fax', 'address',
                  'map_location', 'other_information', 'current_pricing')

class PortSerializer(serializers.ModelSerializer):
    port = PortListSerializer()
    district_list_id = serializers.PrimaryKeyRelatedField(queryset=DistrictList.objects.all(), write_only=True)
    class Meta:
        model = PortDetail

    def create(self, validated_data):
        port_data = validated_data.pop('port')
        port = PortList.objects.create(**port_data)
        PortDetail.objects.create(port=port, **validated_data)
        return PortDetail
序列化程序.py

from location.models import CountryList, DistrictList

class PortList(models.Model):
    name = models.CharField(max_length=45)
    countryList_id = models.ForeignKey(CountryList, models.SET_NULL, blank=True, null=True, verbose_name='related country')
    iso_code = models.CharField(max_length=10)
    short_code = models.CharField(max_length=10, null=True, blank=True)
    status = models.BooleanField(default=True)

    def __str__(self):
        return self.name

class PortDetail(models.Model):
    port = models.OneToOneField(PortList, models.CASCADE, verbose_name='related port', primary_key=True)
    phone = models.CharField(max_length=15)
    district_list_id = models.ForeignKey(DistrictList, models.SET_NULL, blank=True, null=True,
                                         verbose_name='related district')
    email = models.EmailField()
    fax = models.CharField(max_length=100, null=True, blank=True)
    address = models.TextField()
    map_location = models.CharField(max_length=45, null=True, blank=True)
    other_information = models.TextField(null=True, blank=True)
    current_pricing = models.IntegerField(null=True, blank=True)

    def __str__(self):
        return self.port.name+' Details'
from rest_framework import serializers
from port_manager.models import PortList, PortDetail
from location.models import CountryList, DistrictList

class PortListSerializer(serializers.ModelSerializer):
    countryList_id = serializers.PrimaryKeyRelatedField(queryset=CountryList.objects.all(), write_only=True)
    class Meta:
        model = PortList
        fields = ('name', 'countryList_id', 'iso_code')

class PortDetailSerializer(serializers.ModelSerializer):
    district_list_id = serializers.PrimaryKeyRelatedField(queryset=DistrictList.objects.all(),)
    class Meta:
        model = PortDetail
        fields = ('port', 'phone', 'district_list_id', 'email', 'fax', 'address',
                  'map_location', 'other_information', 'current_pricing')

class PortSerializer(serializers.ModelSerializer):
    port = PortListSerializer()
    district_list_id = serializers.PrimaryKeyRelatedField(queryset=DistrictList.objects.all(), write_only=True)
    class Meta:
        model = PortDetail

    def create(self, validated_data):
        port_data = validated_data.pop('port')
        port = PortList.objects.create(**port_data)
        PortDetail.objects.create(port=port, **validated_data)
        return PortDetail
现在,当我使用CURLPOST发送到端点时,它会插入数据库中的两个表中,但会引发错误(400)

提交样品后请求

curl -H "Authorization: Token afab77f7c9320d396442eb1aef9a3bd5de54c3ce" -X POST -d '{"port":{"name":"Singapore", "countryList_id":"3", "iso_code":"SIN", "short_code":"898"},"district_list_id":"9", "email":"asd@aassd.com", "fax":"23423432", "other_information":"adasd sdas", "address":"asdas asd", "phone":"123412312"}' http://example.org/api/v1/portcombined/
Django错误日志中的完整堆栈:

Internal Server Error: /api/v1/portcombined/
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/site-packages/django/core/handlers/base.py", line 149, in get_response
    response = self.process_exception_by_middleware(e, request)
  File "/usr/local/lib/python3.5/site-packages/django/core/handlers/base.py", line 147, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.5/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/usr/local/lib/python3.5/site-packages/django/views/generic/base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python3.5/site-packages/rest_framework/views.py", line 466, in dispatch
    response = self.handle_exception(exc)
  File "/usr/local/lib/python3.5/site-packages/rest_framework/views.py", line 463, in dispatch
    response = handler(request, *args, **kwargs)
  File "/usr/local/lib/python3.5/site-packages/rest_framework/decorators.py", line 53, in handler
    return func(*args, **kwargs)
  File "/home/gpsl/sites/container/src/port_manager/views.py", line 143, in port_merged
    return JSONResponse(serializer.data, status=201)
  File "/usr/local/lib/python3.5/site-packages/rest_framework/serializers.py", line 503, in data
    ret = super(Serializer, self).data
  File "/usr/local/lib/python3.5/site-packages/rest_framework/serializers.py", line 239, in data
    self._data = self.to_representation(self.instance)
  File "/usr/local/lib/python3.5/site-packages/rest_framework/serializers.py", line 472, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
  File "/usr/local/lib/python3.5/site-packages/rest_framework/serializers.py", line 463, in to_representation
    attribute = field.get_attribute(instance)
  File "/usr/local/lib/python3.5/site-packages/rest_framework/relations.py", line 157, in get_attribute
    return get_attribute(instance, self.source_attrs)
  File "/usr/local/lib/python3.5/site-packages/rest_framework/fields.py", line 80, in get_attribute
    instance = getattr(instance, attr)
AttributeError: 'ForwardManyToOneDescriptor' object has no attribute 'countryList_id'

感谢大家花时间仔细阅读这些内容。

问题在于上下文没有传递给嵌套序列化程序。您的
PortSerializer
类应该有一个
\uuuu init\uuuu
方法,并且在那里您应该显式地将上下文传递给嵌套的序列化程序。请参见下面的示例:

class PortSerializer(serializers.ModelSerializer):
    def __init__(self, *args, **kwargs):
        super(PortSerializer, self).__init__(*args, **kwargs)
        self.fields['port'] = PortListSerializer(context=self.context)

我认为,您不应该使用
countryList\u id
modelfield。因为,默认情况下,Django返回具有
object\u id
的对象的id

如果使用
countryList
重命名模型,并从API传递
countryList
,Django肯定会获得
countryList
对象