Pinax源代码分析14 - photos, photologue
url
(r'^photos/', include('photos.urls')),
Models
photos 利用了 第三方 app photologue:
from photologue.models import *
photos.models.Image 继承了 photologue.models.ImageModel:
class Image(ImageModel):
……
继承了ImageModel之后,Image会自动获得几个域,例如 image 和 view_count。同时也会获得几个方法。
逻辑与模板
urlpatterns = patterns('',
# 全部图片 all photos or latest photos
url(r'^$', 'photos.views.photos', name="photos"),
# 图片详细信息 a photos details
url(r'^details/(?P<id>/d+)/$', 'photos.views.details', name="photo_details"),
# 上传图片 upload photos
url(r'^upload/$', 'photos.views.upload', name="photo_upload"),
# 当前用户的图片 your photos
url(r'^yourphotos/$', 'photos.views.yourphotos', name='photos_yours'),
# 指定用户的图片 a members photos
url(r'^member/(?P<username>[/w]+)/$', 'photos.views.memberphotos', name='photos_member'),
# 删除图片 destory photo
url(r'^destroy/(/d+)/$', 'photos.views.destroy', name='photo_destroy'),
# 编辑图片 edit photo
url(r'^edit/(/d+)/$', 'photos.views.edit', name='photo_edit'),
)
views.details 除了显示图片的信息之外,用户还可以将图片添加到自己参加的小组或项目,同时也可以将图片从小组或者项目中删除。
为了使用projects关联photos,它需要定义如下的域:
class Project(models.Model):
……
photos = generic.GenericRelation(Pool)
……
details.html 载入了photos app 自己定义的 photo_tags,不过没有使用。使用了第三方Django_flag定义的flagtags。
{% extends "photos/base.html" %}
{% load photo_tags %}
{% load flagtags %}
<div class="form-toggle">
<p><span id="flag-toggle"><img src="{{MEDIA_URL}}pinax/images/silk/icons/flag_red.png" />{% trans "Flag as inappropriate" %}</span></p>
<div id="flag-form" style="display: none;">
{% flag photo request.user.id %}
</div>
</div>
photologue
项目地址:http://code.google.com/p/django-photologue/
wiki:http://code.google.com/p/django-photologue/w/list
photos.models.Image使用了photologue的ImageModel。
详细文档如下(摘自http://code.google.com/p/django-photologue/wiki/ImageModel ):
ImageModel
它是一个抽象类,继承与该类的Django model会增加一些域和行为,以提供图像的改变大小功能、缓存、记录浏览次数、增强和特效、倒影、水印和旋转等等。
Fields
继承ImageModel 后会增加的域,这些域名将成为保留字,且不能被子类覆盖:
image
Type: ImageField
保存着指向原照片文件的路径。Stores the file path of the original image.
date_taken
Type: DateTimeField
拍摄日期,视图从EXIF 信息中摘取,失败则使用创建的时间。
view_count
Type: PositiveIntegerField
图像被浏览的次数。英文没看明白。
The number of times a PhotoSize with increment_count set to true has been requested for this image.
crop_from
Type: CharField
如果该图像需要被切割,那么从哪个方向切割。
The position that this image will be cropped from if required.
|
top |
|
left |
center |
right |
|
bottom |
|
effect
Type: ForeignKey
给图像应用的PhotoEffect 特效。
Explicitly applies a specific PhotoEffect to this image. This setting will override any effect applied to the PhotoSize requested.
Commonly Used Methods
在下面的方法中,”SIZE”都应该被替换为PhotoSize的“name”。
For the following methods the text "SIZE" should be replaced with the "name" of the desired PhotoSize.
get_SIZE_photosize
返回指定名字的PhotoSize model。例如有一个名为thumbnail的PhotoSize。
Returns the PhotoSize model with that name.
>>> myphoto.get_thumbnail_photosize()
<PhotoSize: thumbnail>
get_SIZE_size
返回指定名字的PhotoSize 的宽度和高度。如果文件不存在会生成文件并且将它缓存起来。感觉英文原文不对。
Returns a tuple containing the actual width and height of the image file on disk in pixels. The file will be generated and cached if not already available.
>>> myphoto.get_thumbnail_size()
(150, 75)
get_SIZE_url
返回指定名字的PhotoSize 的相对URL,如果文件不存在就创建并且缓存。
Returns a relative URL for the size specified. The file will be generated and cached if not already available.
>>> myphoto.get_thumbnail_url()
u'/media/photologue/photos/cache/myfile_thumbnail.jpg'
This is also the method you should use to insert sized photos into your templates:
{% for photo in photos %}
<img src="{{ photo.get_thumbnail_url }}">
{% endfor %}
get_SIZE_filename
返回指定名字的PhotoSize 在硬盘上的路径。如果文件不存在也不会创建。
Returns the path to the file on disk. The file will NOT be generated if it does not already exists.
Admin Integration
但你继承了ImageModel 之后,你就可以使用admin缩略图的功能了。只要在ModelAdmin中的"list_display"属性中添加"admin_thumbnail"就可以了。
When you inherit from the ImageModel class you get Photologues admin thumbnails for free. Just add "admin_thumbnail" to the "list_display" property of your ModelAdmin class:
from myapp.models import MyPhoto
MyPhotoAdmin(admin.ModelAdmin):
list_display = ['title', 'admin_thumbnail']
admin.site.register(MyPhoto, MyPhotoAdmin)
Example
下面是一个简单但是能够工作的例子,一个继承了ImageModel的自定义Model。
Here is a (very) simple, but real world, example of a custom model that inherits from the ImageModel abstract class.
from django.contrib.auth.models import User
from photologue.models import ImageModel
class UserPortrait(ImageModel):
user = models.OneToOneField(User, primary_key=True)
下面我们可以在shell或者admin界面创建一个 PhotoSize:
Now we can create a new PhotoSize through the shell or admin interface:
>>> from photologue.models import PhotoSize
>>> PhotoSize.objects.create(name='avatar', width=60, height=60, crop=True)
剩下的工作就是在模板中添加新的用户头像
All that's left is to add our new user portraits in a template
<div id="user_info">
<h1>{{ user.get_full_name }}</h1>
<img id="user_avatar" src="{{ user.userportrait.get_avatar_url }}">
</div>
PhotoSize
PhotoSize model 可以被看做是一些列的参数,Photologue利用它们用来自动处理图片和改变图片大小。这些参数包括输出大小,压缩质量,特效和水印。定义PhotoSize的数量没有限制,由于Photologue只在被显示告知的时候才会处理你的图片,所以你不需要担心硬盘空间的浪费。
The PhotoSize model can be viewed as a named set of parameters that Photologue uses to automatically resize and process your images. These paramters include output dimensions, compression quality, effects and watermarks. There is no limit to the number of PhotoSize models you can define and because Photologue only process your images when explicitly told to, you don't have to worry about your disk space being wasted.
How Photologue Resize Your Images
可以指定最大的宽度、高度或者同时指定两者。也可以让Photologue将图片切割到一个精确的大小。
Photo sizes are very flexible in the way your images are resized. You can resize to a maximum width, height or both. You can also have Photologue crop your images to an exact set of dimensions.