简体   繁体   English

Django:如何将字节 object 保存到 models.FileField?

[英]Django: how save bytes object to models.FileField?

My web application has the following structure:我的 web 应用程序具有以下结构:

  1. backend with Django带有 Django 的后端
  2. frontend with React. React 前端。

I have a form with React.我有一个 React 表单。 I send a file from client form and I receive the file in my Django application with an APIView.我从客户端表单发送一个文件,并在我的 Django 应用程序中使用 APIView 接收该文件。

I receive a m3u file as bytes object.我收到一个 m3u 文件作为字节 object。

b'------WebKitFormBoundaryIaAPDyj9Qrx8DrWA\r\nContent-Disposition: 
form-data; name="upload"; 
filename="test.m3u"\r\nContent-Type: audio/x- 
mpegurl\r\n\r\n#EXTM3U\n#EXTINF:-1 tvg-ID="" tvg-name="...

I would save the file in a Django model to a models.FileField and convert bytes object to m3u file.我会将文件保存在 Django model 到 models.FileField 并将字节 object 转换为 m3u 文件。 How you do it?你是怎么做到的?

  1. models.FileField ( models.ImageField ) needs django.core.files.base.File like objects ex) models.FileField ( models.ImageField ) 需要django.core.files.base.File像对象 ex)

    • django.core.files.images.ImageFile

    • django.core.files.base.ContentFile

  2. ImageFile or ContentFile needs two args. ImageFileContentFile需要两个参数。

    1. IO object : which has seek() method (ex) io.BytesIO ). IO 对象:它有seek()方法(例如) io.BytesIO )。

    2. name : str .名称: str (important! without name, it will not works). (重要!没有名字,它不会工作)。

  3. bytes object doesn't have IO's methods(ex) seek() ). bytes 对象没有 IO 的方法(例如) seek() )。 it should be converted to IO object.它应该转换为 IO 对象。


models.py模型.py

class Message(models.Model):
    image = models.ImageField(upload_to='message_image/%Y/%m', null=True)

views.py or consumers.py or some-where.py views.py 或 consumer.py 或 some-where.py

import io
from django.core.files.images import ImageFile
from myapp.models import Message

def create_image_message(image_bytes):
    image = ImageFile(io.BytesIO(image_bytes), name='foo.jpg')  # << the answer!
    new_message = Message.objects.create(image=image)

You can try:你可以试试:

from django.core.files.base import ContentFile
import base64

file_data = ContentFile(base64.b64decode(fileData))
object.file.save(file_name, file_data)

You can use your file_name with an .m3u extension, and you shall have it.您可以使用带有 .m3u 扩展名的 file_name,您将拥有它。

I solved using temporary file.我使用临时文件解决了。 I used this code:我使用了这个代码:

extM3u = str.encode(body.decode('utf8').split('EXTM3U\n#')[1].split('------WebKitFormBoundary')[0])

fileTemp = NamedTemporaryFile(delete=True, dir='media/tmp')
fileTemp.write(extM3u)
filenameRe = re.compile('.*?filename=[\'"](.*?)[\'"]')
filename = regParse(filenameRe, body.decode('utf8'))
file = File(fileTemp, name=filename)
m3u = M3u(titleField=filename, fileField=file)
m3u.save()

You can use a ContentFile .您可以使用ContentFile To do so:为此:

from django.core.files.base import ContentFile

content_file = ContentFile(file_bytes, name=file_name)
# Assumes MyModel has a FileField called `file`
MyModel.objects.create(file=content_file)

convert string to bytes将字符串转换为字节

bytes_data = ... # bytes

string_data = bytes_data.hex() # this is a string that you can save in TextField in django model


then, to get bytes from the string:然后,从字符串中获取字节:

bytes_data_2 = bytes.fromhex(string_data)

I apologize for the crooked translation, I'm still only learning English. 我为错误的翻译道歉,我还在学习英语。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM