首页 > 代码库 > [ecommerce2] 017 Image Uploads 图片上传

[ecommerce2] 017 Image Uploads 图片上传

pillow安装

pillow是python image库

>pip install pillow

知识介绍

slug

slug:用于生成一个有意义(valid, meaninful)URL  

参考(http://stackoverflow.com/questions/427102/what-is-a-slug-in-django)

比如:http://stackoverflow.com/questions/427102/what-is-a-slug-in-django  后面的“what-is-a-slug-in-django”就是经过slug后的产物

如何使用:

需要使用slugify功能:

from django.utils.text import slugify

slugify(value) 

If value is "Joel is a slug", the output will be "joel-is-a-slug".

It‘s a way of generating a valid URL, generally using data already obtained. For instance, using the title of an article to generate a URL. I‘d advise to generate the slug, using a function, given a title (or other piece of data), rather than setting it manually.

SlugField

也是起到类似作用,只不过这个一般是后台直接添加时使用,比如:

slug = models.SlugField(unique=True) 

这样在后台就有个slug框,填写后,URL中就包含slug中的内容。

创建ProductImage类 

class ProductImage(models.Model):

    product = models.ForeignKey(Product)

    image = models.ImageField(upload_to=image_upload_to)

 

    def __unicode__(self):

       return self.product.title

定义upload_to函数用于处理上传图片的保存,该函数需要接收两个参数instance和filename

upload_to may also be a callable, such as a function. This will be called to obtain the upload path, including the filename. This callable must accept two arguments and return a Unix-style path (with forward slashes) to be passed along to the storage system. The two arguments are:

Argument

Description

instance

An instance of the model where the FileField is defined. More specifically, this is the particular instance where the current file is being attached.

In most cases, this object will not have been saved to the database yet, so if it uses the default AutoFieldit might not yet have a value for its primary key field.

filename

The filename that was originally given to the file. This may or may not be taken into account when determining the final destination path.

入参instance和filename分别为

Product(iPhone Cover) iphone_cover.jpg

其中instance是当前上传图片关联的product对象,filename为上传文件的文件名

 

Upload_to函数返回文件系统存放路径,一般路径在

MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static_in_env", "media_root")

产品子目录可以自定义

from django.utils.text import slugify

def image_upload_to(instance, filename):
	title = instance.product.title
	slug = slugify(title)
	basename, file_extension = filename.split(".")
	new_filename = "%s-%s.%s" %(slug, instance.id, file_extension)
	return "products/%s/%s" %(slug, new_filename)

例子:将iphone_cover.jpg(Product Image)上传给(Product)iPhone Cover 

title, slug, basename, file_extension, new_filename的值分别如下:

iPhone Cover iphone-cover iphone_cover jpg iphone-cover-2.jpg

 

注意同一文件重复上传的结果,以MP3 Player为例,将mp3_player.jpg上传给Product MP3 Player

 

如果是第一次创建ProductImage,instance.id为None

MP3 Player mp3-player mp3_player jpg mp3-player-None.jpg

MP3 Player mp3_player.jpg

同样的名字,如果做第二次修改

MP3 Player mp3-player mp3_player jpg mp3-player-3.jpg

MP3 Player mp3_player.jpg

Currently: products/mp3-player/mp3-player-3.jpg 

同样的名字,如果继续覆盖,文件不会被覆盖,而是增加随机数重新拷贝一个

MP3 Player mp3-player mp3_player jpg mp3-player-3.jpg

MP3 Player mp3_player.jpg

Currently: products/mp3-player/mp3-player-3_7KveE47.jpg 

 

执行migrate

>python manage.py makemigrations
>python manage.py migrate

创建admin接口

from .models import Product,Variation,ProductImage

admin.site.register(ProductImage)

在product_detail_view添加图片显示

 

下面这两个的显示分别如下

                            {{ img.image.file }}

                            {{ img.image.url }}

 

D:\virtualenv\ecommerce-ws\src\static_in_env\media_root\products\mp3-player\mp3-player-None.jpg 

/media/products/mp3-player/mp3-player-None.jpg

MEDIA_URL = ‘/media/‘
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static_in_env", "media_root")

  

 

[ecommerce2] 017 Image Uploads 图片上传