有什么聪明的方法可以在 Django 中使用 Web 套接字保存文件?
are there any clever ways to save files with Web socket in Django?
我建了一个聊天网站,我想我可以添加除了消息之外的发送文件的功能。
但是好像web socket不能发送文件或者图片。
我的解决方案是,当发送文件时,我使用 api 然后获取的消息和文件按时间戳重新排序。但是如果有更好的方法可以实现,我很想知道。
那么,我的问题是
- 是否可以通过 web socket 发送文件并通过 WebsocketConsumer 获取文件?
- 有什么方法可以将这两个过程结合起来吗?
(例如,您发送 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, ...)
我建了一个聊天网站,我想我可以添加除了消息之外的发送文件的功能。 但是好像web socket不能发送文件或者图片。 我的解决方案是,当发送文件时,我使用 api 然后获取的消息和文件按时间戳重新排序。但是如果有更好的方法可以实现,我很想知道。
那么,我的问题是
- 是否可以通过 web socket 发送文件并通过 WebsocketConsumer 获取文件?
- 有什么方法可以将这两个过程结合起来吗? (例如,您发送 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, ...)