Django REST Framework:序列化ImageField

时间:2017-02-28 19:20:46

标签: python django django-rest-framework

Django REST Framework及其序列化程序与使用ImageField的模型有关的问题

以下是我的模型的代码:

class Photo(models.Model):
    id = models.AutoField(primary_key=True)
    image_file = models.ImageField(upload_to=generate_image_filename_and_path,
                                   width_field="image_width",
                                   height_field="image_height",
                                   null=False,
                                   blank=False)
    image_width = models.IntegerField(null=False, blank=False)
    image_height = models.IntegerField(null=False, blank=False)

这是序列化器:

class PhotoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Photo
        fields = ('image_file',)
        read_only = ('id', 'image_width', 'image_height')

id,image_width和image_height被设置为read_only字段,因为我希望它们由模型类生成。在首次创建模型实例时,我甚至无法提供ID。

我遇到了很多麻烦。在当前状态下,我有一个看起来像这样的测试:

class PhotoSerializerTestCase(TestCase):
    def test_native_data_type_serialization(self):
        img_file = create_generic_image_file('test_img.jpg',
                                             'image/jpeg')

        p = Photo(image_file=img_file)
        p.save()

        serialization = PhotoSerializer(p)

        expected_id = p.id
        expected_image_width = p.image_width
        expected_image_height = p.image_height

        print(serialization)
        actual_id = serialization.data['id']
        actual_image_width = serialization.data['image_width']
        actual_image_height = serialization.data['image_height']

        self.assertEqual(expected_id, actual_id)
        self.assertEqual(expected_image_width, actual_image_width)
        self.assertEqual(expected_image_height, actual_image_height)

这是我调用的函数,用于为测试创建通用图像文件:

def create_generic_image_file(name, content_type):

    path = '\\test_files\\test_image_generic.jpg'
    file_path = BASE_DIR + path
    file_name = name
    content = open(file_path, 'rb').read()

    image_file = SimpleUploadedFile(name=file_name,
                                    content=content,
                                    content_type=content_type)

    return image_file

在目前的状态下,我留下了如下错误:

Creating test database for alias 'default'...
..PhotoSerializer(<Photo: Photo object>):
    image_file = ImageField()
E.
======================================================================
ERROR: test_native_data_type_serialization (photo_broker.test_serializers.PhotoSerializerTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "<local_path>\test_serializers.py", line 25, in test_native_data_type_serialization
    actual_id = serialization.data['id']
KeyError: 'id'

我甚至无法回忆起我之前收到的所有不同的错误,但我确信当这个错误被清除时它们会弹出。

编辑:

好的,我通过将所有字段移回PhotoSerializer.Meta.fields而不是PhotoSerializer.Meta.read_only来清除键错误。现在我回到原来的一个问题。让我解释一下测试:

def test_create_model_from_serializer(self):
    img_file = create_generic_image_file('test_img.jpg',
                                         'image/jpeg')

    data = {'image_file': img_file,
            'id': 7357,
            'image_width': 1337,
            'image_height': 715517}

    s = PhotoSerializer(data=data)
    print(type(s))
    print(s.is_valid())
    print(s)

这产生了明显可爱的输出,并且序列化器在没有咳嗽的情况下验证,但这不是我想要的。 ID和尺寸应由模型计算。不是串行器的任何值。

如果我从fields属性中删除它们,那么我也永远无法将它们放入我的序列化中。这就是我需要它们的地方。

或者我在这里感到困惑,实际上有一个有效的用例,我最初正常创建模型,而不通过序列化器?

0 个答案:

没有答案