foxfirefey: A guy looking ridiculous by doing a fashionable posing with a mouse, slinging the cord over his shoulders. (geek)
[personal profile] foxfirefey posting in [community profile] django_dev
Here's an example of making an admin page that lets people reorder the items through drag and drop. It's *fairly* genericized already--you can use the same template for multiple data types--and has the potential to be MORE generic by creating a generic view sort of thing, but I haven't done that yet.

All you need is a model that has a (Integer or PositiveInteger) field named 'order'.

The form will let you reorder the items by drag and drop and save them, and also lets you link to the usual form to add an item.

The view function example:

def reorder_datatypes(request):
    t = loader.get_template('admin/reorder.html')
    # can change what fields you can edit within the drag and drop items, like name
    DataTypeFormSet = modelformset_factory(DataType, extra = 0,
        fields=('display_name', 'code_name', 'order'))
    if request.method == "POST":
        formset = DataTypeFormSet(request.POST)
        if formset.is_valid():
            # reset the order to what's been saved
            formset = DataTypeFormSet(queryset=DataType.objects.order_by('order'))
        formset = DataTypeFormSet(queryset=DataType.objects.order_by('order'))
    c = Context({
        'title': 'Data Type Order',
        'formset': formset,
        # change this to the admin add link of the item you are reordering
        'new_item_url': reverse('admin:MyApp_datatype_add'),
    return HttpResponse(t.render(c))

The template (you might have to change where your Javascript libraries are):

{% extends "admin/base_site.html" %}

{% block extrahead %}
<script type="text/javascript" src="/media/js/jquery.js"></script>
<link type="text/css" href="/media/jquery-ui/css/smoothness/jquery-ui-1.8.4.custom.css" rel="stylesheet" />
<script type="text/javascript" src="/media/jquery-ui/js/jquery-ui-1.8.4.custom.min.js"></script>

ul.order_list {
        list-style: none outside none;

li.order_item {
        padding: 10px;
        border: 1px solid #CCCCCC;
        margin: 5px;
        border-left: 5px solid #999;
        list-style: none outside none;

.hidden {
        display: none;

.red {
    background-color: #F00;


<script type="text/javascript">

    // hide order fields 

    // turns the list into a sortable one 
        update: function(event, ui) {
            var item_order =  $(this).sortable('toArray');
            // redo all of the order numbers in multiples of 10
            for( i = 0; i < item_order.length; i++ ) {
                var item = item_order[i];
                var new_order = (i + 1) * 10;
                var selector = '#'+item+' span.order input';


{% endblock %}

{% block content %}

<li><a href="{{ new_item_url }}">Add new item</a></li>

<form method="post" action="">
{{ formset.management_form }}
<ul class="order_list">
{% for form in formset.forms %}
<li class="order_item" id="item-{{ forloop.counter }}">
{% for field in form.visible_fields %}

{# include hidden fields #}
{% if forloop.first %}
        {% for hidden in form.hidden_fields %}
        {{ hidden }}
        {% endfor %}
{% endif %}

{% if "order" in field.html_name %}
<span class="order">
{% else %}
<span class="description">
{% endif %}

{{ field.errors }}
{{ field.label_tag}}
{{ field }}


{% endfor %}
{% endfor %}

<p><input type="submit" value="Save" /></p>

{% endblock %}


django_dev: The Django logo. (Default)
Developing with Django

April 2014

131415161718 19

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags