#django #django-channels
#django #django-каналы
Вопрос:
Я создал сайт чата и думаю, что могу добавить функцию отправки файлов помимо сообщения. Но, похоже, веб-сокет не может отправлять файлы или изображения. Мое решение заключается в том, что при отправке файла я использую api, а затем извлекаемые сообщения и файлы переупорядочиваются по метке времени. Но если есть лучшие способы добиться этого, я действительно хочу знать.
Итак, мой вопрос
- Можно ли отправлять файлы с помощью веб-сокета и получать их с помощью WebsocketConsumer?
- Есть ли какие-либо способы объединить эти два процесса? (напр. вы отправляете предварительную ссылку на файлы и сохраняете их как 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)
Я не знаю, какая информация необходима, чтобы разобраться в этом, поэтому я вставляю только модель. Если что-то неясно, дайте мне знать.
Спасибо 🙂
Комментарии:
1. @minglyu Это сработало! Спасибо! если вы ответите на мой вопрос ниже. Я могу принять ваш ответ.
Ответ №1:
Вы можете кодировать изображение в 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, ...)