首页 > 代码库 > [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 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 图片上传