Django在媒体文件夹内创建另一个媒体文件夹。

3

我是Django的初学者,这正是它的用途。 我按照文档中的说明进行操作,但可能出了些问题?

从管理页面中,我添加/设置产品并选择“图像”,然后在保存时创建一个缩略图并尝试将其保存在“/media/uploads/”中,但实际上它创建了另一个“media”文件夹,并且图像存储在“/media/media/uploads/img.png”中,而网站上的路径是“/media/uploads/img.png”。以下是代码:

/shop/settings.py:
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # or even 'media/'

/shop/urls.py:
urlpatterns = [
    ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

添加完成后,在我的Product模型中,我做如下操作:

/apps/store/models.py:
class Product(models.Model):
    ...
    image = models.ImageField(upload_to='media/uploads/', blank=True, null=True)
    thumbnail = models.ImageField(upload_to='media/uploads/', blank=True, null=True)
    ...

    def save(self, *args, **kwargs):
        self.thumbnail = self.make_thumbnail(self.image)
        super().save(*args, **kwargs)

    @staticmethod
    def make_thumbnail(image, size=(512, 512)):
        if not image:
            return

        img = Image.open(image)
        if img.mode in ('RGBA',):  # converting image to RGB if it's RGBA
            img.load()
            rgb_convert = Image.new('RGB', img.size, 0)
            rgb_convert.paste(img, mask=img.split()[3])
            img = rgb_convert

        img.thumbnail(size)

        thumb_io = BytesIO()
        img.save(thumb_io, 'PNG', quality=80)
        thumb = File(thumb_io, name=image.name)
        return thumb

我尝试将“upload_to”更改为“uploads /”,然后它会将文件存储在正确的位置,但它在网站上的路径也会更改为“/ uploads / img.png”,而实际上应该是“/ media / uploads / img.png”。
可能哪里出了问题呢? 谢谢!

你到底如何渲染现场路径?我认为模板中的渲染有误。 - Willem Van Onsem
@WillemVanOnsem 只是使用 <img src="{{ p.thumbnail }}">,但无论如何它都会创建另一个文件夹,这很奇怪。 - Iipal
2个回答

5

upload_to=…参数[Django-doc]是相对于MEDIA_ROOT的。如果您想将其存储在media目录下的uploads目录中,则可以使用以下方式上传:

class Product(models.Model):
    # …
    thumbnail = models.ImageField(upload_to=<b>'uploads/'</b>, blank=True, null=True)

为了呈现URL,您需要使用.url属性[Django-doc],所以:
{% if p.thumbnail %}
    <img src="{{ p.thumbnail<b>.url</b> }}">
{% endif %}

这里的{% if p.thumbnail %}是必要的,用于检查NULL/None值。


正如我所描述的那样,这并没有帮助,因为现在它正在寻找 'http://127.0.0.1:8000/uploads/img.png' 中的图像,而通过这些更改,它存储在 'http://127.0.0.1:8000/media/uploads/img.png' 中。 - Iipal
@lipal:已经存储了,但是您正在错误地渲染它,您不应该使用{{ p.thumbnail }},而应该使用{{ p.thumbnail.url }}。这将运行逻辑以将文件转换为URL路径,并在其前面添加MEDIA_URL - Willem Van Onsem
尝试执行此操作时,异常信息为:“异常值:'thumbnail'属性没有与之关联的文件。” - Iipal
@lipal:很可能你以前存储的缩略图确实无法工作。对于这些,你需要手动更新数据库。但是,如果你上传了一个新的图片并为那个对象测试它,它通常应该可以工作。 - Willem Van Onsem

2

这是因为你在设置中写了"upload_to='media/uploads'"。 根据你的设置,Django将创建一个名为media的文件夹,而由于你写了"media/uploads",uploads文件夹位于media文件夹内,而media文件夹又在设置中被声明为主要媒体文件夹。因此只需写

class Product(models.Model):
…
thumbnail = models.ImageField(upload_to='uploads/', blank=True, null=True)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接