Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.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
Django 如何让序列化程序从模型中的依赖字段返回数据?_Django_Python 3.x_Django Models_Serialization_Django Serializer - Fatal编程技术网

Django 如何让序列化程序从模型中的依赖字段返回数据?

Django 如何让序列化程序从模型中的依赖字段返回数据?,django,python-3.x,django-models,serialization,django-serializer,Django,Python 3.x,Django Models,Serialization,Django Serializer,我正在使用Django 2和Python 3.7。我已经把这些模型安装好了。一个(合作社)依赖于另一个(合作社类型),使用多对多 class CoopTypeManager(models.Manager): def get_by_natural_key(self, name): return self.get_or_create(name=name)[0] class CoopType(models.Model): name = models.CharFie

我正在使用Django 2和Python 3.7。我已经把这些模型安装好了。一个(合作社)依赖于另一个(合作社类型),使用多对多

class CoopTypeManager(models.Manager):

    def get_by_natural_key(self, name):
        return self.get_or_create(name=name)[0]


class CoopType(models.Model):
    name = models.CharField(max_length=200, null=False, unique=True)

    objects = CoopTypeManager()


class CoopManager(models.Manager):
    # Look up by coop type
    def get_by_type(self, type):
        qset = Coop.objects.filter(type__name=type,
                                   enabled=True)
        return qset

    # Look up coops by a partial name (case insensitive)
    def find_by_name(self, partial_name):
        queryset = Coop.objects.filter(name__icontains=partial_name, enabled=True)
        print(queryset.query)
        return queryset

    # Meant to look up coops case-insensitively by part of a type
    def contains_type(self, types_arr):
        filter = Q(
            *[('type__name__icontains', type) for type in types_arr],
            _connector=Q.OR
        )
        queryset = Coop.objects.filter(filter,
                                       enabled=True)
        return queryset


class Coop(models.Model):
    objects = CoopManager()
    name = models.CharField(max_length=250, null=False)
    types = models.ManyToManyField(CoopType)
    address = AddressField(on_delete=models.CASCADE)
    enabled = models.BooleanField(default=True, null=False)
    phone = PhoneNumberField(null=True)
    email = models.EmailField(null=True)
    web_site = models.TextField()
我设置了以下序列化程序,旨在以JSON格式返回数据

class CoopTypeField(serializers.PrimaryKeyRelatedField):

    queryset = CoopType.objects

    def to_internal_value(self, data):
        if type(data) == dict:
            cooptype, created = CoopType.objects.get_or_create(**data)
            # Replace the dict with the ID of the newly obtained object
            data = cooptype.pk
        return super().to_internal_value(data)

...
class CoopTypeSerializer(serializers.ModelSerializer):
    class Meta:
        model = CoopType
        fields = ['id', 'name']

    def create(self, validated_data):
        """
        Create and return a new `CoopType` instance, given the validated data.
        """
        return CoopType.objects.create(**validated_data)

    def update(self, instance, validated_data):
        """
        Update and return an existing `CoopType` instance, given the validated data.
        """
        instance.name = validated_data.get('name', instance.name)
        instance.save()
        return instance


class CoopSerializer(serializers.ModelSerializer):
    types = CoopTypeSerializer(many=True)
    address = AddressTypeField()

    class Meta:
        model = Coop
        fields = ['id', 'name', 'types', 'address', 'phone', 'enabled', 'email', 'web_site']
        extra_kwargs = {
            'phone': {
                'required': False,
                'allow_blank': True
            }
        }

    def to_representation(self, instance):
        rep = super().to_representation(instance)
        rep['types'] = CoopTypeSerializer(instance.types).data
        rep['address'] = AddressSerializer(instance.address).data
        return rep

    def create(self, validated_data):
        #"""
        #Create and return a new `Snippet` instance, given the validated data.

        coop_types = validated_data.pop('types', {})
        instance = super().create(validated_data)
        for item in coop_types:
            coop_type, _ = CoopType.objects.get_or_create(name=item['name'])  #**item)
            instance.types.add(coop_type)

        return instance
但是,依赖字段“type”总是返回为“null”,尽管我可以看到数据库中存在有效数据。下面是运行curl请求时发生的情况

curl -v --header "Content-type: application/json" --request GET "http://127.0.0.1:8000/coops/?contains=resource"
[{"id":348,"name":"Garden Resources of Woodlawn (GRoW)","types":{"name":null}

如何编辑序列化程序以使其返回依赖类型的值?

尝试删除
rep['types']=CoopTypeSerializer(instance.types)。数据
到_表示(…)
方法

def to_representation(self, instance):
    rep = super().to_representation(instance)
    rep['types'] = CoopTypeSerializer(instance.types).data
    rep['address'] = AddressSerializer(instance.address).data
    return rep

看起来您不需要
来表示
CoopSerializer
的方法,请尝试删除它。第一个解决方案只生成了一个空数组(“[]”),第二个解决方案生成了错误,'AttributeError:在尝试获取序列化程序
CoopTypeSerializer
上的字段
name
的值时,获取了AttributeError。。。原始异常文本为:“QuerySet”对象没有属性“name”。“更新了第二个选项。”
def to_representation(self, instance):
    rep = super().to_representation(instance)
    rep['types'] = CoopTypeSerializer(instance.types.all(), many=True).data
    rep['address'] = AddressSerializer(instance.address).data
    return rep