有什么聪明的方法可以在 Django 中使用 Web 套接字保存文件?

are there any clever ways to save files with Web socket in Django?

我建了一个聊天网站,我想我可以添加除了消息之外的发送文件的功能。 但是好像web socket不能发送文件或者图片。 我的解决方案是,当发送文件时,我使用 api 然后获取的消息和文件按时间戳重新排序。但是如果有更好的方法可以实现,我很想知道。

那么,我的问题是

  1. 是否可以通过 web socket 发送文件并通过 WebsocketConsumer 获取文件?
  2. 有什么方法可以将这两个过程结合起来吗? (例如,您发送 link 个临时文件并将它们存储为 FileField?)

型号

from django.db import models
from django.contrib.auth import get_user_model

User = get_user_model()


class Contact(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='contact_user')
    friends = models.ManyToManyField('self', blank=True, related_name='friends')


    def __str__(self):
        return self.user.name

class Message(models.Model):
    contact = models.ForeignKey(Contact, related_name='message', on_delete=models.CASCADE)
    content = models.TextField()
    timestamp = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.contact.user.name

class File(models.Model):
    contact = models.ForeignKey(Contact, related_name='file', on_delete=models.CASCADE)
    file = models.FileField()
    timestamp = models.DateTimeField(auto_now_add=True)

class Chat(models.Model):
    participants = models.ManyToManyField(Contact, related_name='chats')
    messages = models.ManyToManyField(Message, blank=True)
    files = models.ManyToManyField(File, blank=True, null=True)
    timestamp = models.DateTimeField(auto_now_add=True)


    def last_30_messages(self):
        return self.messages.order_by('-timestamp').all()[:30]


    def __str__(self):
        return "{}".format(self.pk)

我不知道需要什么信息来解决这个问题,所以我只粘贴模型。如果有什么不清楚的地方,请告诉我。

谢谢:)

您可以在前端将图像编码为base64格式,在服务器端将图像编码为decode,如果您不太关心图像,我建议您在浏览器中压缩图像质量,因为它可以将图像尺寸缩小到较大的内容。

在服务端,可以读取解码后的字节为ContentFile,这样就可以和Django ORM完美配合:

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

def base64_decode(data, name):
    '''decode the base64 string and create a compatible 
       file that Django recognize
    '''
    format, imgstr = data.split(';base64,') 
    ext = format.split('/')[-1]
    data = ContentFile(base64.b64decode(imgstr), name=name + '.' + ext)
    return data

# save the file
file = base64_decode(message, 'file_name')
Yourmodel.objects.create(file=file, ...)