I can't figure out why I'm getting this error "The serializer field might be named incorrectly and not match any attribute or key on the GenericRelatedObjectManager
instance. Original exception text was: 'GenericRelatedObjectManager' object has no attribute 'country'.". I been working on this for days, Can someone help me please? What is wrong with my code? Thanks in advance.
I want to create a nested serializer that has a CRUD functionality. Planning to use this in my DRF.
I have 3 interrelated models namely Company, Address, and Country.
Model Structure
Company
|__Address (GenericForeignKey)
|___Country (ForeignKey)
Company Model
from django_countries.fields import CountryField
class SalesClientCompany(models.Model):
address = GenericRelation(
Address,
null=True,
blank=True,
)
Address Model
class Address(models.Model):
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE,)
object_id = models.UUIDField(
primary_key=False,
unique=False,
default=uuid.uuid4,
blank=True,
null=True,
)
content_object = GenericForeignKey()
country = models.ForeignKey(
Country,
verbose_name=_("Country"),
to_field='country',
blank=False,
on_delete=models.CASCADE,
)
Country Model
from django_countries.fields import CountryField
class Country(SmardtAbstractHistory):
country = CountryField(
unique=True,
)
name = SmardtTranslateField(
models.CharField(
max_length=50,
null=True,
)
)
Serializers
from rest_framework import serializers
from django.contrib.contenttypes.models import ContentType, ContentTypeManager
from models.client_companies import SalesClientCompany
from country.models.countries import Country
from models.addresses import Address
class CountrySerializer(serializers.ModelSerializer):
class Meta:
model = Country
fields = ('country',)
class ClientCompanyAddressSerializer(serializers.ModelSerializer):
country = CountrySerializer()
# country = serializers.SlugRelatedField(queryset=Country.objects.all(), slug_field='country')
class Meta:
model = Address
fields = ('line_first', 'line_second', 'province', 'country', 'postal_code',)
class ClientCompanySerializer(serializers.ModelSerializer):
address = ClientCompanyAddressSerializer()
class Meta:
model = SalesClientCompany
fields = ['id', 'name', 'address', 'email', 'phone', 'type', 'company_directory']
def create(self, validated_data):
company = SalesClientCompany(
name=validated_data['name'],
email=validated_data['email'],
.....
)
company.save()
content_type = ContentType.objects.get_for_model(SalesClientCompany)
company_address = Address(
content_type=content_type,
object_id=company.pk,
content_object=company,
country=validated_data['address']['country'],
.....
)
company_address.save()
return company
Inspect Serializer
ClientCompanyAddressSerializer():
line_first = CharField(allow_blank=True, label='Address Line 1', max_length=255, required=False)
line_second = CharField(allow_blank=True, label='Address Line 2', max_length=255, required=False)
province = CharField(allow_blank=True, label='State/Province/Region', max_length=255, required=False)
country = SlugRelatedField(queryset=Country.objects.all(), slug_field='country')
postal_code = CharField(allow_blank=True, label='Zip/Postal Code', max_length=255, required=False)
View
class ClientCompanyCreate( generics.ListCreateAPIView ):
queryset = SalesClientCompany.objects.all()
serializer_class = ClientCompanySerializer
Even though your serializers are aware of each other, the serializers don't know how to link the models together. You need to specify the source
parameter when initialising the nested serializer, and provide the value of the related_name
of the foreign key in the model.
For example:
class ClientCompanyAddressSerializer(serializers.ModelSerializer):
country = CountrySerializer(source='country_set')
class Meta:
model = Address
fields = ('line_first', 'line_second', 'province', 'country', 'postal_code',)
In your code, you did not provide an explicit related_name
when defining your ForeignKey
field, so Django automatically generated related name country_set
(model name + '_set').
See also this answer ("Django Rest Framework Nested Serializers") and this answer ("Include intermediary (through model) in responses in Django Rest Framework").
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With