2016-04-06 9 views
2

Django tabanlı bir gönderi yönetim uygulaması üzerinde çalışıyorum. Django Rest Framework'ü entegre ettik ve birkaç son noktaya maruz kaldık. Django Rest Framework yazılabilir iç içe serilaştırıcı, AttributeError

Şimdi "port_manager" denilen Django uygulaması aşağıdaki etti modelleri

...

models.py Şimdi

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' 

serializers.py

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 

Ben kullanarak son noktaya POST CURL veritabanındaki tabloların her iki eklediği ancak hata yükseltmek (400)

kıvırmak örnek POST talebi

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":"[email protected]", "fax":"23423432", "other_information":"adasd sdas", "address":"asdas asd", "phone":"123412312"}' http://example.org/api/v1/portcombined/ 
Django hata kaydından

Tam yığın:

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' 

sayesinde Zaman ayırdığınız ve tüm bunlardan geçtiğiniz için hepiniz.

cevap

1

Sorun, içeriğin iç içe geçmiş serileştiricilere geçirilmemesidir. Sizin PortSerializer sınıfınızın bir __init__ yöntemine sahip olması ve orada bağlamı iç içe geçmiş serileştiricinize açıkça iletmeniz gerekir.

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

Bence sen countryList_id modelfield kullanmamalısınız: Aşağıdaki örnek bakınız. Çünkü, varsayılan olarak Django, nesnenin kimliğini object_id ile döndürür.

Modelinizi countryList ile yeniden adlandırır ve API'dan countryList geçirirseniz, Django kesinlikle CountryList nesnesini alır.