我如何从不同的模型上传一个或多个文件,而不是使用 ModelSerializer 的外键关系存储它们?

问题描述

我有以下用例。我希望能够拥有一个包含多个文件的项目,因此我创建了一个模型来存储文件和另一个模型来存储项目,例如您还可以将图像上传Item

models.py

class File(models.Model):
    """Class to represent a file."""

    name = models.TextField()

    file = models.FileField(upload_to='item_attachments/%Y/%m/%d/')

    item = models.ForeignKey("Item",on_delete=models.CASCADE,related_name='attachments',null=True)

    added_on = models.DateTimeField(auto_Now_add=True)
    

class Item(models.Model):
    """Class to represent an item..."""

    label = models.TextField(null=True)

    photo = models.ImageField(null=True,upload_to='item_images/%Y/%m/%d/')

    name = models.TextField()

然后我创建我的序列化程序:

serializers.py

class FileSerializer(serializers.ModelSerializer):
    """Serializer for File."""

    class Meta: # pylint: disable=too-few-public-methods
        """Class to represent Metadata of the object."""
        model = File
        fields = [ 'id','name','file','added_on','item' ]

class ItemSerializer(serializers.ModelSerializer):
    """Serializer for Item."""

    attachments = FileSerializer(
                            many=True,allow_null=True,required = False
                        )

    class Meta: # pylint: disable=too-few-public-methods
        """Class to represent Metadata of the object."""
        model = Item
        fields = [  'id','label','photo','attachments']
        read_only_fields = ['id']

    def create(self,validated_data):
        obj = Item.objects.create(**validated_data)
        print(self)
        print(validated_data)
        return obj

最后我创建了 REST 端点:

views.py


class FileViewset(viewsets.ModelViewSet): # pylint: disable=too-many-ancestors
    """API Endpoint to return the list of categories"""
    queryset = File.objects.all()
    serializer_class = FileSerializer
    pagination_class = None

class ItemViewset(viewsets.ModelViewSet): # pylint: disable=too-many-ancestors
    """API Endpoint to return the list of items"""
    queryset = Item.objects.all()
    serializer_class = ItemSerializer

我可以将 POST 转换为 FileViewset 并且效果很好:

post_file

如果我尝试对带有附件的项目执行 POST,它不起作用,它会为附件留下一个空数组:

item_query

因此,经过一些研究,我认为我必须覆盖 create 方法。但是当我尝试做这一步时,我的问题就来了。如果我像以前那样打印 print(validated_data)。我看不到我在查询中发送的 attachments

如果我打印 print(self) 变量,我会看到附件以与图像类似的方式进入服务器,但不知何故它在数据验证中丢失了。

我该怎么做才能通过验证?

添加更多信息,这是自我打印的内容

ItemSerializer(context={'request': <rest_framework.request.Request: POST '/api/v1/item/'>,'format': None,'view': <inventory.views.ItemViewset object>},data=<QueryDict: {'label': ['00000003'],'name': ['HDMI Cable Delete me'],'photo': [<InMemoryUploadedFile: example.png (image/png)>],'attachments': [<InMemoryUploadedFile: example.png (image/png)>]}>):
...
...
attachments = FileSerializer(allow_null=True,many=True,required=False):
        id = IntegerField(label='ID',read_only=True)
        name = CharField(style={'base_template': 'textarea.html'})
        file = FileField(max_length=100)
        added_on = DateTimeField(read_only=True)
        item = PrimaryKeyRelatedField(allow_null=True,queryset=Item.objects.all(),required=False)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...