django-photo-albums’s documentation

django-photo-albums is a pluggable django image gallery app.

Image galleries can be attached to any Django model. And thanks to django 1.1 url namespaces it is possible to have multiple ‘albums’ app instances (for example, for different models) that use different sets of templates, different permission rules, have dedicated integration test suites and are available from different urls.

Each image gallery provide functionality for image viewing, editing, uploading, reordering, marking/unmarking as main and deleting.

django-photo-albums requires Django >= 1.1 (or svn version with url namespaces), setuptools for installation, django-generic-images for image management and django-annoying.

Sorl-thumbnails should be mentioned as a very good optional dependency for generating thumbnails, but you can use any other library if you want.

Testing if app instance is integrated correctly (at least that templates don’t raise exceptions) is easy because base class for integration testcases is provided.

Installation

$ pip install django-photo-albums

or:

$ easy_install django-photo-albums

or:

$ hg clone http://bitbucket.org/kmike/django-photo-albums/
$ cd django-photo-albums
$ python setup.py install

Then add ‘photo_albums’ and ‘generic_images’ to your INSTALLED_APPS in settings.py and run ./manage.py syncdb (syncdb is not needed if django-generic-images was already installed).

Basic use

PhotoAlbumSite

To add image gallery for your model you should complete following steps:

  1. Create album site instance and plug it’s urls to urlconf:

    from photo_albums.urls import PhotoAlbumSite
    accounts_photo_site = PhotoAlbumSite(instance_name = 'user_images', 
                             queryset = User.objects.all(), 
                             template_object_name = 'album_user',
                             has_edit_permission = lambda request, obj: request.user==obj) 
    urlpatterns += patterns('', url(r'^accounts/', include(accounts_photo_site.urls)),)
    

Please note that if you deploy multiple albums (ex. for different models), you must provide unique instance_name for each instance to make url reversing work.

Included urls looks like <object_id>/<app_name>/<action> or <object_id>/<app_name>/<image_id>/<action>, where object_id is the id of object which is gallery attached to, app_name is “albums” by default, image_id is image id :) and action is performed action (view, edit, etc). It is possible to use slug instead of object’s id (look at object_regex and lookup_field parameters).

  1. Create the necessary templates.
  2. Link people to image gallery using {% url .. %} template tags.

You can use these urls (assuming that user_images in an instance name, album_user is object for which gallery is attached to, image is image in gallery):

{% url user_images:show_album album_user.id %}

{% url user_images:edit_album album_user.id %}

{% url user_images:upload_main_image album_user.id %}

{% url user_images:upload_images album_user.id %}

{% url user_images:show_image album_user.id image.id %}

{% url user_images:edit_image album_user.id image.id %}

{% url user_images:delete_image album_user.id image.id %}

{% url user_images:set_as_main_image album_user.id image.id %}

{% url user_images:clear_main_image album_user.id image.id %}

{% url user_images:reorder_images album_user.id %}

{% url user_images:set_image_order album_user.id %}
class photo_albums.urls.PhotoAlbumSite(instance_name, queryset, app_name='album', object_regex='\d+', lookup_field='pk', extra_context=None, template_object_name='object', has_edit_permission=<function <lambda> at 0x1a1bb70>, context_processors=None, edit_form_class=<class 'photo_albums.forms.ImageEditForm'>, upload_form_class=<class 'generic_images.forms.AttachedImageForm'>, upload_formset_class=<class 'django.forms.formsets.AttachedImageFormFormSet'>)

Constructor parameters:

instance_name: String. Required. App instance name for url reversing. Must be unique.

queryset: QuerySet. Required. Albums will be attached to objects in this queryset.

object_regex: String. Optional, default is ‘d+’. It should be a URL regular expression for object in URL. You should use smth. like ‘[wd-]+’ for slugs.

lookup_field: String. Optional, default is ‘pk’. It is a field name to lookup. It may contain __ and follow relations (ex.: userprofile__slug).

app_name: String. Optional, default value is ‘album’. Used by url namespaces stuff.

extra_context: Dict. Optional. Extra context that will be passed to each view.

template_object_name: String. Optional. The name of template context variable with object for which album is attached. Default is ‘object’.

has_edit_permission: Optional. Function that accepts request and object and returns True if user is allowed to edit album for object and False otherwise. Default behaviour is to always return True.

context_processors: Optional. A list of callables that will be used as additional context_processors in each view

edit_form_class: Optional. ModelForm subclass to be used in edit_image view

upload_form_class: Optional. ModelForm subclass to be used in upload_main_image view

upload_formset_class: Optional. ModelFormSet to be used in upload_images view

Templates used by django-photo-albums

Templates should be placed in templates/albums/<app_name> folder. App_name should be the name of queryset model’s app as it appears in contenttypes table (e.g. ‘auth’ for User).

Each view have at least 2 variables in context:

  • <template_object_name>: object for which gallery is attached to (the name of variable

    is set in PhotoAlbumsSite constructor, default is object)

  • current_app: app name, ‘albums’ by default

The views included in django-photo-albums make use of 7 templates:

  • show_album.html displays entire album

  • edit_album.html displays entire album. Used by edit_album view.

  • reorder_images.html displays entire album. Used by reorder_images view.

    Theese 3 templates have images variable in context with iterable of all images in gallery.

  • show_image.html - displays one image. Has image, prev and next

    variables in context. prev and next are id’s of previous and next (by image.order field) images in gallery.

  • upload_images.html - displays the formset for bulk image upload.

    Formset is of PhotoFormSet type (defined in photo_albums.forms module) and is available as formset context variable.

  • upload_main_image.html - displays form for uploading one image. Uploaded

    image becomes main in gallery. Has form in context, it’s a form of type AttachedImageForm defined in generic_images.forms module.

  • confirm_delete.html - displays confirmation dialog for deleting image.

    Has image in context. Should have a form that do POST request to delete view on submit.

Views

Views for use with PhotoAlbumSite.

photo_albums.views.clear_main_image
mark image as not main and redirect to show_image view
photo_albums.views.delete_image
delete image if request method is POST, displays confirm_delete.html template otherwise
photo_albums.views.edit_album
same as show_album view but with login_required decorator
photo_albums.views.edit_image
show one image, use login_required decorator and provide edit form
photo_albums.views.set_as_main_image
mark image as main and redirect to show_image view
photo_albums.views.show_album(request, object_id, album_site, template_name='show_album.html')
Show album for object using show_album.html template
photo_albums.views.show_image(request, object_id, image_id, album_site)
show one image
photo_albums.views.upload_images
upload several images at once
photo_albums.views.upload_main_image
upload 1 image and make it main image in gallery

Testing

Integration testing

django-photo-albums provides base class (photo_albums.test_utils.AlbumTest) for writing integration tests for app instances.

The example usage:

from accounts.urls import accounts_photo_site
from photo_albums import test_utils

class UserAlbumTest(test_utils.AlbumTest):
    # existing user's data
    username = 'obiwanus' 
    password = 'vasia'
    
    # fixtures to be loaded (at least with users, images and 
    # objects with galleries)
    fixtures = ['my_fixtures']
    
    # app instance which is to be tested
    album_site = accounts_photo_site
    
    # we don't need edit_image view and don't create template for it
    # so it should be excluded from testing
    excluded_views = ['edit_image']
    
    # id of object for which album is attached
    album_for_id = 4
    
    # if slugs are in use:
    # album_for_id = 'my_object_slug'
    
    # id's of various images: 2 images in album (second is nedded if tou want 
    # to test reordering) and one image in other album to test permission checks
    image_in_album_id = 48
    image2_in_album_id = 66
    image_in_other_album_id = 42    

If you don’t use fixtures you can override setUp method and create necessery objects there.

class photo_albums.test_utils.AlbumTest(methodName='runTest')

Bases: generic_utils.test_helpers.ViewTest

check(view, status, kwargs=None)
test_auth_views()
test_forbidden_views()
test_public_views()
test_reorder()

Table Of Contents

This Page