【问题标题】:django renaming image file while uploading上传时django重命名图像文件
【发布时间】:2023-01-13 06:00:41
【问题描述】:

我在 django 中开发一个社交媒体应用程序,想重命名上传内容中的所有图像,以便更容易地重用它们(将它们放入 pdf 是最终目标,现在文件名与上传和我不知道如何将这些路径放入 pdf --> 解决方案可能是对它们进行编号)。

文件名应重命名为:postimg{num_post} 所有职位都有编号。具体编号或帖子应在图像文件的文件名末尾。

模型.py


def post_images(instance, filename):
    ext = filename.split('.')[-1]
    filename = "%s_%s.%s" % (instance.post.num_post, ext)
    return os.path.join('uploads', filename)

class Post(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    num_post = models.IntegerField(default=0)
    image = models.ImageField(upload_to='post_images')
    caption = models.TextField(max_length=300)
    created_at = models.DateTimeField(auto_now_add=True)
    number_of_likes = models.IntegerField(default=0)
    number_of_dislikes = models.IntegerField(default=0)
    def __str__(self):
        return self.caption

视图.py

def upload(request):
    if request.method == 'POST':
        #user = request.user.username
        image = request.FILES.get('image_upload')
        #--> how to rename the image file to "post{num_post}.jpg"
        caption = request.POST['caption']
        num_post = Post.objects.count()+1
        new_post = Post.objects.create(image=image, caption=caption, num_post=num_post)
        new_post.save()


        #create pdf
        buffer = io.BytesIO()


        #get the image
        #img_file = Image.open(f'{os.getcwd()}/{post.image.url}').convert('RGB')

        #img_file = f'media/post_images/postimg{num_post}'
        #x_start = 0
        #y_start = 0


        #saving it on the server
        folder_path = f"media/post{num_post}.pdf"
        folder_name = os.path.basename(folder_path)


        p = canvas.Canvas(folder_name)

        #p.drawImage(img_file, x_start, y_start, width=120, preserveAspectRatio=True, mask='auto')
        p.drawString(200, 300, new_post.caption)
        p.drawString(200, 100, str(new_post.created_at))
        p.drawString(200, 600, str(new_post.id))

        #p.drawText(new_post.caption)
        #p.drawImage(new_post.image)
        p.showPage()
        p.save()
        buffer.seek(0)
        return redirect('/'), folder_path

    else:
        return redirect('/')

所以最后我应该能够通过使用将图像放入pdf中:

        img_file = f'media/post_images/postimg{num_post}'
        x_start = 0
        y_start = 0
        p.drawImage(img_file, x_start, y_start, width=120, preserveAspectRatio=True, mask='auto')

我已经能够通过使用现有文件名将图像转换为 pdf,但由于应该为每个帖子自动生成 pdf,我认为图像名称需要可变。

现在,它不起作用。图像没有重命名,但也没有错误显示。所以功能似乎没有达到图像?我如何让它发挥作用?

谢谢你的任何建议。 :) 我是 Django 的新手...任何解释都有帮助。

【问题讨论】:

    标签: python django django-models file-rename image-upload


    【解决方案1】:

    让我们从模型字段开始:

    class Post(models.Model):
        ...
        image = models.ImageField(upload_to='post_images')
        ...
    

    它没有显示任何错误,因为您正在将文件上传到 'post_images' 文件夹并且没有调用具有此类名称的函数。这也是您的文件未重命名的原因。

    要调用重命名函数,只需删除单引号:

    image = models.ImageField(upload_to=post_image)
    

    虽然,由于这一行,它不会起作用:

    def post_images(instance, filename):
        ...
        filename = "%s_%s.%s" % (instance.post.num_post, ext)
        ...
    

    哪里有两个问题。首先,instance 是一个post 对象实例,您试图以错误的方式访问它。第二个是尝试用两个参数格式化三个字符串。话虽如此:

    def post_images(instance, filename):
        ext = filename.split('.')[-1]
        filename = 'postimg{}.{}'.format(instance.num_post, ext)
        return os.path.join('uploads', filename)
    

    现在,与视图相关,使用django formsmodel form)始终是一个好习惯,它还有助于编写更少的代码,同时做更多的事情(比如验证数据):

    表单.py

    from django import forms
    from .models import Post
    
    class PostCreateForm(forms.ModelForm):
        class Meta:
            model = Post
            fields = ['image', 'caption']
    

    视图.py

    from django.shortcuts import render
    from .models import Post
    from .forms import PostCreateForm
    
    # Create your views here.
    def post_create(request):
        if request.method == 'POST':
            form = PostCreateForm(request.POST, request.FILES)
    
            if form.is_valid():
                form.cleaned_data['num_post'] = Post.objects.count() + 1
                Post.objects.create(**form.cleaned_data)
        else:
            form = PostCreateForm()
    
        return render(request, 'post_create.html', {'form': form})
    

    在这个view 中,在检查数据是否有效后,我们更新有效数据字典并创建对象。此外,由于我们使用的是.create(),因此之后没有必要保存该对象。

    post_create.html

    {% extends 'base.html' %}
    
    {% block content %}
    <form action="{% url 'post:create' %}" enctype="multipart/form-data" method="post">
        {% csrf_token %}
        {{form.as_p}}
        <button type="submit">Create</button>
    </form>
    {% endblock content %}
    

    最后,让convert an Image to pdf。为此,让我们制作一个列出所有帖子的模板,并使用 FileResponse 导出 pdf 文件的视图

    post_list.html

    {% extends 'base.html' %}
    
    {% block content %}
        {% for post in posts %}
        <form action="{% url 'post:convert-to-pdf' post.id %}" method="post">
            {% csrf_token %}
            {{post}}
            <button type="submit">Convert Post Image</button>
        </form>
        {% endfor %}
    {% endblock content %}
    

    视图.py

    from django.shortcuts import get_object_or_404
    from django.http import FileResponse
    from PIL import Image
    import os
    
    ...
    def post_list(request):
        posts = Post.objects.all()
        
        return render(request, 'post_list.html', {'posts': posts})
    
    def convert_to_pdf(request, pk=None):
        post = get_object_or_404(Post, id=pk)
    
        image = Image.open(f'{os.getcwd()}/{post.image.url}').convert('RGB')
        image.save(f'{os.getcwd()}/tmp/converted_image.pdf')
        image.close()
    
        f = open(f'{os.getcwd()}/tmp/converted_image.pdf', 'rb')
        return FileResponse(f)
    

    网址.py

    from django.urls import path
    from core import views
    
    app_name = 'post'
    
    urlpatterns = [
        path('post/', views.post_create, name='create'),
        path('posts/', views.post_list, name="list-post"),
        path('convert/<uuid:pk>/', views.convert_to_pdf, name='convert-to-pdf'),
    ]
    

    【讨论】:

    • 嗨尼科。这非常有帮助。我没有在答案中发布整个项目代码,因为我只需要解决命名问题。 pdf 将自动生成并存储在服务器上(客户端不知道)。我已经用 ReportLab 做到了这一点,但由于文件名是特定的,所以无法将图像放入其中
    • 现在,我在上传文件夹中添加了重命名图像的解决方案,并且运行良好。 pdf 是在上传功能中创建的。我将在帖子中编辑完整内容。对不起,我以前没有这样做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-24
    相关资源
    最近更新 更多