1. 程式人生 > >[ecommerce2] 017 Image Uploads 圖片上傳

[ecommerce2] 017 Image Uploads 圖片上傳

itl cell ica tro int image nat ecommerce read

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 AutoField, it 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 圖片上傳