【问题标题】:Display a picture via Django saved on mysql database通过保存在 mysql 数据库中的 Django 显示图片
【发布时间】:2018-02-05 22:55:51
【问题描述】:

我想用 Django 显示一张图片,该图片已经保存在 mysql 数据库中。在所有方法中,我发现有人使用models.Imagefield(upload_to='path'),但我认为这会将文件保存到此目录中,其他计算机的人以后将无法访问。 那么问题来了,如何直接访问数据库并显示图片而不在中间保存呢?

我已经设法在 python 中做到这一点,但我不太确定如何将代码实现到 models.py 中。 我的方法是这样的:

class mysqlpicture(models.Model):
    #mysqlpic=something?

    def openpic():
        connection = pymysql.connect(user='root', passwd='***',
                                     host='localhost',
                                     database='db')

        cursor = connection.cursor()

        sql1='select * from Pictures'
        cursor.execute(sql1)
        data=cursor.fetchall()

        mysqlpic=io.BytesIO(data[1][0])#one means second element of column zero 

        #img=Image.open(mysqlpic)
        #img.show()
        cursor.close()
        return mysqlpic

然后我尝试在views.py 中将mysqlpic直接提供给httpresponse,如下所示:

def MysqlView(request):
    query_results = mysqlpicture.objects.all()
    template = loader.get_template('polls/pic.html')
    context = {
        'query_results': query_results,
    }
    return HttpResponse(template.render(context, request))

使用模板pic.html插入图片如下:

{% for n in query_results %}
<mysqlpic src="{{ n.mysqlpic.url }}" />
{% endfor %}

有人知道如何以正确的方式做到这一点吗?

【问题讨论】:

    标签: python mysql django django-models


    【解决方案1】:

    是的,使用 ImageField 确实允许其他计算机的人稍后访问它。它继承了 FileField 的所有属性和方法,它将文件上传到 upload_to 中指定的路径中的服务器,并将此路径保存到您的数据库中以保留其引用。当您在模型实例中调用 save() 方法时,所有这些都会发生。

    然后,您可以通过在模板中调用 your_instance.image_field.url 来创建 URL 以构建链接。还记得看一下MEDIA_ROOTMEDIA_URL,它们分别告诉 Django 用于保存文件的服务器根路径和处理从 MEDIA_ROOT 提供的媒体的 url。

    【讨论】:

    • 如果数据库中只存储图片的路径,那是不是意味着其他人需要以某种方式与我的计算机进行通信才能真正获取图片的数据,或者这意味着什么路径何时保存在数据库中?
    • 正如丹尼尔所说,这并不意味着...保存在数据库中的路径与MEDIA_ROOT中定义的根路径相关。当您调用 your_instance.image_field.url 时,将以您在 MEDIA_URL 中指定的格式创建一个链接,以便其他用户能够访问该图片。
    【解决方案2】:

    您可以为此目的使用BinaryField

    但如 django 文档中所述:

    尽管您可能会考虑将文件存储在数据库中,但请考虑在 99% 的情况下这是糟糕的设计。

    from django.db import models
    
    class MysqlPicture(models.Model):
        mysqlpic = models.BinaryField()
        # ...
    

    然后在模板中显示你可以将二进制数据转换为base64:

    from base64 import b64encode
    
    def mysql_view(request):
        query_results = MysqlPicture.objects.all()
        template = loader.get_template('polls/pic.html')
        context = {
            'images': [b64encode(obj.mysqlpic) for obj in query_results],
        }
        return HttpResponse(template.render(context, request))
    

    模板:

    {% for image in images %}
        <img src="data:;base64,{{ image }}">
    {% endfor %}
    

    【讨论】:

    • 如何在模型中返回 BinaryField,以便稍后显示图片?
    • 例如,@user8496104 将您的二进制数据转换为 base64。我更新了答案,请检查。
    猜你喜欢
    • 2013-12-20
    • 1970-01-01
    • 2014-11-22
    • 2017-03-04
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多