【问题标题】:AssertionError at ************** in Django-Rest FrameworkDjango-Rest 框架中 ************** 处的 AssertionError
【发布时间】:2016-06-02 17:58:42
【问题描述】:

我正在研究 Django rest-framework 中的 ModelSerializers。

models.py

from __future__ import unicode_literals
from django.db import models
from django.contrib.postgres.fields import ArrayField
from django.contrib.postgres.fields import HStoreField
from django.contrib.postgres.validators import KeysValidator

    class Component(models.Model):
        component_name = models.CharField(max_length=50)
        allowed_extensions = ArrayField(models.CharField(max_length=50))

        def __str__(self):
            return self.component_name

    class Image_Type(models.Model):
        image_name = models.CharField(max_length=30)
        def __str__(self):
            return self.image_name
    class Image_Component(models.Model):
        component_name = models.ForeignKey('Component')
        image_name = models.ForeignKey('Image_Type')
    class Image_Meta(models.Model):
        image_component = models.ForeignKey('Image_Component',on_delete=models.CASCADE,)
        component_id = models.IntegerField()
        image_count = models.IntegerField(default=0)
        version = models.CharField(max_length=10)

    class Image(models.Model):
        image_meta = models.ForeignKey('Image_Meta',on_delete=models.CASCADE,)
        image_path = models.URLField(max_length=200)
        order = models.IntegerField()
        version = models.CharField(max_length=10)


    class Feature(models.Model):
        image_component = models.ForeignKey('Image_Component',on_delete=models.CASCADE,)
        feature_value = HStoreField()
        def save(self,*args,**kwargs):
            if Feature.objects.filter(feature_value__has_keys=['size', 'quality' , 'format']):
                super(Feature, self).save(*args, **kwargs)
            else:
                print("Incorrect key entered")

serializers.py

from rest_framework import serializers
from models import Component , Image_Type , Image_Component , Image , Feature , Image_Meta
from django.contrib.postgres.fields import ArrayField
from django.contrib.postgres.fields import HStoreField


class ComponentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Component
        field = {'component_name','allowed_extensions'}


class Image_TypeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Image_Type
        field = {'image_name'}



class Image_ComponentSerializer(serializers.ModelSerializer):
    component_name = ComponentSerializer()
    image_name = Image_TypeSerializer()
    class Meta:
        model = Image_Component
        field = {'component_name','image_name'}

    def create(self, validated_data):
        component_data = validated_data.pop('component_name')
        image_data = validated_data.pop('image_name')
        image_component = Image_Component.objects.create(**validated_data)

        for component_data in component_data:
            Component.objects.create(image_component=image_component, **component_data)

        for image_data in image_data:
            Image_Type.objects.create(image_component=image_component, **image_data)

        return image_component

class Image_MetaSerializer(serializers.ModelSerializer):
    image_component = Image_ComponentSerializer()
    class Meta:
        model = Image_Meta
        field = {'image_component','component_id' , 'image_count', 'version'}

class ImageSerializer(serializers.ModelSerializer):
    image_meta = Image_MetaSerializer()
    class Meta:
        model = Image_Meta
        field = {'image_meta' , 'image_path' , 'order' , 'version'}

class FeatureSerializer(serializers.ModelSerializer):
    image_component = Image_ComponentSerializer()
    class Meta:
        model = Feature
        field = {'image_component' , 'feature_value'}

urls.py

from django.conf.urls import patterns , include , url
from rest_framework.urlpatterns import format_suffix_patterns
from imagedata import views

urlpatterns = patterns('',
    url(r'^api/component$',views.Component.as_view()),
    url(r'^api/image_type$',views.Image_Type.as_view()),
    url(r'^api/image_meta$',views.Image_Meta.as_view()),
    url(r'^api/image_component$',views.Image_Component.as_view()),
    url(r'^api/image$',views.Image.as_view()),
    url(r'^api/feature$',views.Feature.as_view()),
)

urlpatterns = format_suffix_patterns(urlpatterns)

它适用于 componentimage_type 模型,也就是说,如果我尝试更新这些表,我可以为这两个模型做。但是对于 image_component 模型,每当我尝试更新表时,我都会收到错误消息:

AssertionError at /imagedata/api/image_component
The `.create()` method does not support writable nestedfields by default.
Write an explicit `.create()` method for serializer `imagedata.serializers.Image_ComponentSerializer`, or set `read_only=True` on nested serializer fields.
Request Method: POST
Request URL:    http://127.0.0.1:8000/imagedata/api/image_component
Django Version: 1.9
Exception Type: AssertionError
Exception Value:    
The `.create()` method does not support writable nestedfields by default.
Write an explicit `.create()` method for serializer `imagedata.serializers.Image_ComponentSerializer`, or set `read_only=True` on nested serializer fields.
Exception Location: /Library/Python/2.7/site-packages/rest_framework/serializers.py in raise_errors_on_nested_writes, line 724
Python Executable:  /usr/bin/python
Python Version: 2.7.10

http://127.0.0.1:8000/imagedata/api/image_component 的页面如下所示:

我可能完全错了,但我认为文本字段应该要求从分别存在于组件和 Image_Type 表中的 component_nameimage_type 的值集中进行选择但他们不是。我做错了什么?以及如何纠正?

Django-Admin 也没有问题。它工作得很好。

【问题讨论】:

    标签: python django postgresql django-rest-framework


    【解决方案1】:

    首先我想说的是,我很确定您遇到的错误是在 Image_ComponentSerializer 上添加 .create 方法之前。

    由于Image_Component 基于 2 个外键,如果您希望在 API 中同时包含两个外键,只需将您的序列化程序更改为此(删除 .create 方法,因为不需要):

    class Image_ComponentSerializer(serializers.ModelSerializer):
        class Meta:
            model = Image_Component
    

    所以没有自定义序列化器,但是这会影响Image_Component 对象的表示,它将显示FK 字段的ID。要改变这种行为,我会像这样覆盖 .to_representation 方法:

    def to_representation(self, obj):  
        ret = {'component_name': ComponentSerializer(instance=obj.component_name).data,
               'image_name': ImageTypeSerializer(instance=obj.image_name).data}
        return ret
    

    因此,输入将是 FK 的 id,输出将基于每个字段的自定义序列化器。

    【讨论】:

    • 我遇到了另一个问题。问题在于 Feature 表中的 feature_value 字段中使用的 Hstore 字段。尝试在 Django-Rest 框架页面中保存特征值时,存储的特征值是空白的。你能帮我弄清楚一些事情吗?
    猜你喜欢
    • 2016-06-19
    • 1970-01-01
    • 2015-05-31
    • 2018-07-31
    • 2023-03-23
    • 1970-01-01
    • 2016-08-10
    • 1970-01-01
    • 2017-04-01
    相关资源
    最近更新 更多