简体   繁体   English

使用 Django 中的 FileField 显示图像

[英]DIsplay images using FileField in Django

I have a Django app which converts uploaded pdf files into images .我有一个Django 应用程序,它将上传的 pdf 文件转换为图像 The upload part and conversion part are working fine but I am having issues on displaying the converted images .上传部分和转换部分工作正常,但我在显示转换后的图像时遇到问题 I am using ModelForms to upload the pdf files using the FileField , converting them into.png and finally displaying them on a new page.我正在使用 ModelForms 使用FileField上传pdf文件,将它们转换为.png,最后在新页面上显示它们。 If I used an ImageField , I won't be able to upload pdf files.如果我使用ImageField ,我将无法上传 pdf 文件。 So I am using a FileField because that is the purpose of the app, to convert pdf to png!所以我使用FileField因为这是应用程序的目的,将 pdf 转换为 png!

models.py模型.py

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

# Create your models here.

class UserUploadModel(models.Model):
    
    user = models.ForeignKey(User, on_delete = models.CASCADE, null = True)
    file = models.FileField(upload_to = 'file_uploads')

forms.py forms.py

from django import forms
from django.forms import ClearableFileInput
from app1.models import UserUploadModel

class UserUploadForm(forms.ModelForm):
    

    class Meta:

        model = UserUploadModel
        fields = ['file']
        widgets = {
            'file' : ClearableFileInput(attrs = {'multiple': True}),
        }

views.py视图.py

from django.shortcuts import render, redirect
from app1.forms import UserUploadForm
from app1.models import UserUploadModel
from app1.convert import convert_file
from app1.transfer import move_dir
import os
from project1 import settings
from django.contrib.auth.decorators import login_required

@login_required
def home(request):
    
    if request.method == 'POST':
        form = UserUploadForm(request.POST, request.FILES)
        
        if form.is_valid():
            f = form.save()
            f.user = request.user
            f.save()
          
            files = request.FILES.getlist('file')
                        
            f_list = []
            
            if files:
                for i in files:
                    file_instance = UserUploadModel(file = i)
                    file_instance.save()
                    f_list.append(file_instance.file.path)
                
                [convert_file(j) for j in f_list]
                
    
                src_dir = os.getcwd()
                dest_dir = os.path.join(src_dir, 'media/')            
                move_dir(src_dir, dest_dir, '*.png')

            
            return redirect('app1-display')
        
    else:
        
        form = UserUploadForm()
    
    return render(request, 'app1/home.html', {'form' : form})

@login_required
def display(request):
    
    return render(request, 'app1/display.html')

home.html主页.html

{%extends "app1/base.html"%}
{%block content%}

    <form method="POST" enctype="multipart/form-data">
      {%csrf_token%}
      {{form.as_p}}
      <input type="submit">
    </form>

{%endblock content%}

EDIT 1: the display.html is empty because I do not know how to display images stored in a directory .编辑 1: display.html 是空的,因为我不知道如何显示存储在目录中的图像 If I use ImageField , I can use the url of the image to display it but I am using FileField to upload , convert it to.png and then I store the images in a folder inside the BASE_DIR.如果我使用ImageField ,我可以使用图像的 url来显示它,但我使用 FileField上传,将其转换为.png,然后将图像存储在 BASE_DIR 内的文件夹中。 Now how do I display the images stored in a folder in BASE_DIR?现在如何显示存储在 BASE_DIR 文件夹中的图像?

Also I only want to show the images for the current logged in user另外我只想显示当前登录用户的图像

EDIT 2: display.html编辑2: display.html

<!DOCTYPE>
<html>
<head>
    <title></title>
</head>
<body>

    {%if user.is_authenticated%}
        <h2>User: {{request.user.username}}</h2>
    {%endif%}

    {%for i in x%}
        <img src={{ i.file.url }}>
    {%endfor%}
    
</body>
</html>

I got it to work!我让它工作了! The reason that duplicate images were being saved in directory was because I was saving the form form.save() which will first save the last of the 2 uploaded images (so 1 image saved:) and then I was saving the instance of each and every uploaded file (2 images saved!) which results in 3 images!将重复图像保存在目录中的原因是因为我保存了表单form.save()它将首先保存 2 个上传图像中的最后一个(因此保存了 1 个图像:),然后我保存了每个和每个上传的文件(保存 2 张图片!)产生 3 张图片! Hence I changed my view to this:-因此我改变了看法:-

views.py视图.py

from django.shortcuts import render, redirect
from app1.models import UserUploadModel
from app1.forms import UserUploadForm
# Create your views here.

def home(request):
    
    if request.method=='POST':
        
        form = UserUploadForm(request.POST, request.FILES)
        
        if form.is_valid():            
            files = request.FILES.getlist('file')                
                
            if files:
                for i in files:
                    file_instance = UserUploadModel(file = i, user = request.user)
                    file_instance.save()
            
        return redirect('app1-display')
    
    else:
        
        form = UserUploadForm()
    
    return render(request, 'app1/home.html', {'form' : form})


def display(request):
    
    x = UserUploadModel.objects.filter(user = request.user)

    context = {
        'x' : x
        }
    
    return render(request, 'app1/display.html', context)

display.html显示.html

<!DOCTYPE>
<html>
<head>
    <title></title>
</head>
<body>

    {%if user.is_authenticated%}
        <h2>User: {{request.user.username}}</h2>
    {%endif%}

    {%if x%}
        {%for i in x%}
            <img src={{ i.file.url }}>
        {%endfor%}
    {%endif%}
</body>
</html>

This will allow user to upload multiple images and display all of them!这将允许用户上传多个图像并显示所有图像! Thanks to @Sunderam Dubey for helping me out with the views.py .感谢@Sunderam Dubey 帮助我解决views.py问题。

You should first send all the images of current logged in user in the context then display it using .url in img tag.您应该首先在上下文中发送当前登录用户的所有图像,然后在img标签中使用.url显示它。

views.py:视图.py:

@login_required
def display(request):
    user_uploads=UserUploadModel.objects.filter(user=request.user)
    context={"user_uploads":user_uploads}
    
    return render(request, 'app1/display.html', context)

app1/display.html: app1/display.html:

<body>
    {% if request.user.is_authenticated %}
        <h2>User : {{request.user.username}}</h2>
    {% endif %}
    <br><br>

    {% for user_upload in user_uploads %}
        <img src="{{user_upload.file.url}}" width='300px'>
        <br><br>
    {% endfor %}
</body>

Note: Models in Django doesn't require model to be the suffix, so you may write the model name as UserUpload instead of UserUploadModel .注意: Django 中的模型不需要 model 作为后缀,因此您可以将 model 名称写为UserUpload而不是UserUploadModel

Additionally, I'd suggest to maintain proper gap between template tags such as it should be {% csrf_token %} not {%csrf_token%} and so on.此外,我建议在模板标签之间保持适当的间隙,例如它应该是{% csrf_token %}而不是{%csrf_token%}等等。

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

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