django-common

The django-common package contains things which speed up the development with django.

Installation

  • Install django-common package with pip or easy_install
  • Append common to the settings.INSTALLED_APPS

Decorators

Contains view’s decorators which automates common tasks.

common.decorators.render_to(template)

Render view’s output with template using RequestContext.

If decorated view returns dict object then wrap it in RequestContext and render the template.

If decorated view returns non dict object then just return this object.

Args:
template:path to template

Example:

@render_to('blog/index.html')
def post_list(request):
    posts = Post.objects.all()
    return {'posts': posts,
            }
common.decorators.ajax(func)

Convert views’s output into JSON.

Decorated view should return dict object.

If request.method is not POST then deny the request.

If view raises Exception then return JSON message with error description.

Pagination

Django-common pagination module dramatically simplifies the pagination task.

You only have to do following things.

In view:

@render_to('foo_list.html')
def foo_list(request):
    qs = Foo.objects.all()
    page = paginate(qs, request)
    return {'page': page,
            }

In template:

<ul>
{% for item in page.object_list %}
    <li>{{ item }}</li>
{% endfor %}
</ul>

{% include "pagination.html" %}

If you want to know how this work under the hood please look at source code.

common.pagination.paginate(qs, request, per_page=15, frame_size=10)

Return extended django.core.paginator.Page object

Args:

qs:queryset which should be paginated
request:django request object
per_page:number of objects per page
frame_size:number of visible pages (does not include first and large page)

Forms

common.forms.build_form(Form, _request, *args, **kwargs)

Build the Form instance.

If request.method is POST then build bound form else build unbound.

Usage example:

@login_required
@render_to('blog/post_create.html')
def post_create(request):
    post = Post(instance=request.user)
    form = build_form(PostForm, request, instance=post)
    if form.is_valid():
        obj = form.save()
        return redirect(obj)
    return {'form': form,
            }
class common.forms.DeleteForm

This form could be used in conjunction with build_form on pages where user have to confirm some action.

Typical example of such page is deletion the some object.

Fields:
next:this is optional field. You can use it to store redirection URL.

Usage example:

@render_to('blog/post_delete.html')
def post_delete(request, postid):
    post = get_object_or_404(Post, pk=postid)
    form = build_form(DeleteForm, request, initial={'next': request.GET.get('next')})
    if form.is_valid():
        post.delete()
        return redirect(form.cleaned_data['next'] or '/')
    return {'form': form,
            'post': post,
           }

Model Fields

class common.fields.AutoOneToOneField

OneToOneField creates dependent object on first request from parent object if dependent oject has not created yet.

More info (in russian): http://softwaremaniacs.org/blog/2007/03/07/auto-one-to-one-field/

Usage example:

# in models.py
class Profile(models.Model):
    user = AutoOneToOneField('auth.User')
    icq = models.IntegerField()

# in some view
user = User.objects.create_user('batman', 'batman@gmail.com', 'Robin')
user.profile.icq = '827873948'
user.profile.save()
class common.fields.JSONField

JSONField allows to store any data which is serialized in JSON under the hood.

Usage example:

# in models.py
class Video(models.Model):
    thumbnails = JSONField()

# in some view
obj = Video()
obj.thumbnails = ['1.jpg', '2.jpg']
obj.save()

Enum

This module provides Enum class which simplifies work with enumerated list of choices. This implementation is specially developed for use in django models.

Example of usage:

from common import enum

class Color(enum.Enum):
    red = enum.Item(1)
    green = enum.Item(2, 'So greeeen')

We defined here two items. They are accessable as Color.red and Color.green. Color.red will give you 1. So Color.red == 1 is True.

First item (Color.red) has the label same to its key i.e., “red”. Second item (Color.green) has the custom label. Labels are used when Color object are queried for the (key, label) pairs. This happens, for example, when we use Color object as the value for the choices argument of django field:

class Fruit(models.Model):
    color = models.IntegerField(choices=Color, default=Color.red)

We can use Color object as choices argument because enum.Enum class provides custom __iter__ method which returs (key, label) pairs.

Also keep in mind that Color.red is not simple integer. It is like integer but has some extra methods. Look example:

Color.green == 2 Color.green.label == “So greeeen” Color.green.key == “green”

Other useful methods of enum.Enum class:

Color.by_value(1) == Color.red
Color.by_key("red") == Color.red
Color.values == [Color.red, Color.green]
Color.random_value() == "Random value choosed from Color items"

Some tests:

# Common usage of enum module >>> class Body(Enum): ... sedan = Item(1, u’Sedan’) ... hatchback = Item(2, u’Hatchback’) >>> set(Body) set([(1, u’Sedan’), (2, u’Hatchback’)]) >>> Body.sedan 1

# Build Enum class from list of tuples >>> Body = build(((1, u’Sedan’), (2, u’Hatchback’))) >>> set(Body) set([(1, u’Sedan’), (2, u’Hatchback’)])

# Specify items with _choices attribute >>> class Body(Enum): ... _choices = ((1, u’Sedan’), (2, u’Hatchback’)) >>> set(Body) set([(1, u’Sedan’), (2, u’Hatchback’)])

# _choices also could be a dict instance >>> class Body(Enum): ... _choices = dict(Sedan=1, Hatchback=2) >>> set(Body) set([(1, ‘Sedan’), (2, ‘Hatchback’)])

# Get enum Item by its value >>> Body.by_value(1).key ‘Sedan’

# Pass arbitrary data to items >>> class Color(Enum): ... red = Item(1, ‘Red’, example=’Apple’) ... green = Item(2, ‘Green’, example=’Tree’) >>> Color.green.example ‘Tree’

Table Of Contents

This Page