序列化程序字段的名称可能不正确,并且与GenericRelatedObjectManager实例上的任何属性或键都不匹配

时间:2019-02-13 07:08:06

标签: django django-rest-framework django-serializer

我无法弄清楚为什么会收到此错误“序列化程序字段的名称可能不正确,并且与GenericRelatedObjectManager实例上的任何属性或键都不匹配。原始异常文本为:'GenericRelatedObjectManager'对象具有没有属性“国家/地区”。”。我已经为此工作了好几天,有人可以帮我吗?我的代码有什么问题?预先感谢。

我想创建一个具有CRUD功能的嵌套序列化程序。计划在我的DRF中使用它。

我有3个相关的模型,即公司,地址和国家。

  • 公司模型有一个名为“ 地址”的字段,它是一个GenericForeignKey。
  • 地址模型具有一个名为“ 国家”的字段,它是ForeignKey。
  • 国家/地区模型是CountryField()。我正在使用django_countries插件。

模型结构

Company
 |__Address (GenericForeignKey)
    |___Country (ForeignKey)

公司型号

from django_countries.fields import CountryField

class SalesClientCompany(models.Model):
            address = GenericRelation(
                Address,
                null=True,
                blank=True,
            )

地址模型

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,
    )

国家/地区型号

from django_countries.fields import CountryField

class Country(SmardtAbstractHistory):

    country = CountryField(
        unique=True,
    )

    name = SmardtTranslateField(
        models.CharField(
            max_length=50,
            null=True,
        )
    )

序列化器

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

检查序列化程序

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)

查看

class ClientCompanyCreate( generics.ListCreateAPIView ):
    queryset = SalesClientCompany.objects.all()
    serializer_class = ClientCompanySerializer

2 个答案:

答案 0 :(得分:3)

即使您的序列化程序彼此了解,但序列化程序也不知道如何将模型链接在一起。初始化nested serializer时,需要指定source参数,并在模型中提供外键的related_name的值。

例如:

class ClientCompanyAddressSerializer(serializers.ModelSerializer):
    country = CountrySerializer(source='country_set')
    
    class Meta:
        model = Address
        fields = ('line_first', 'line_second', 'province', 'country',  'postal_code',)

在您的代码中,定义related_name字段时未提供明确的ForeignKey,因此Django automatically generated related name country_set(模型名称+'_set')。< / p>

另请参见this answer(“ Django Rest Framework嵌套序列化程序”)和this answer(“ 在Django Rest Framework中包含中介(通过模型)< / em>”)。

答案 1 :(得分:0)

对不起,我无法在评论中发布内容,但是序列化程序类中的字段不会是元组。

fields =('line_first','line_second','province','country','postal_code',)