Skip to content

Instantly share code, notes, and snippets.

@Mhs-220
Last active August 5, 2024 20:07
Show Gist options
  • Save Mhs-220/ba07db15128031cce92fa53cae3c959c to your computer and use it in GitHub Desktop.
Save Mhs-220/ba07db15128031cce92fa53cae3c959c to your computer and use it in GitHub Desktop.
Allow ordering apps in the Django admin
{% load i18n %}
{% if app_list %}
{% for app in app_list %}
<div
id="django-app-{{ app.app_label }}"
class="app-{{ app.app_label }} module{% if app.app_url in request.path|urlencode %} current-app{% endif %}"
draggable="true"
style="cursor: move;"
>
<table>
<caption>
<a href="{{ app.app_url }}" class="section" title="{% blocktranslate with name=app.name %}Models in the {{ name }} application{% endblocktranslate %}">{{ app.name }}</a>
</caption>
{% for model in app.models %}
{% with model_name=model.object_name|lower %}
<tr class="model-{{ model_name }}{% if model.admin_url in request.path|urlencode %} current-model{% endif %}">
<th scope="row" id="{{ app.app_label }}-{{ model_name }}">
{% if model.admin_url %}
<a href="{{ model.admin_url }}" {% if model.admin_url in request.path|urlencode %} aria-current="page" {% endif %}>{{ model.name }}</a>
{% else %}
{{ model.name }}
{% endif %}
</th>
{% if model.add_url %}
<td><a href="{{ model.add_url }}" class="addlink" aria-describedby="{{ app.app_label }}-{{ model_name }}">{% translate 'Add' %}</a></td>
{% else %}
<td></td>
{% endif %}
{% if model.admin_url and show_changelinks %}
{% if model.view_only %}
<td><a href="{{ model.admin_url }}" class="viewlink" aria-describedby="{{ app.app_label }}-{{ model_name }}">{% translate 'View' %}</a></td>
{% else %}
<td><a href="{{ model.admin_url }}" class="changelink" aria-describedby="{{ app.app_label }}-{{ model_name }}">{% translate 'Change' %}</a></td>
{% endif %}
{% elif show_changelinks %}
<td></td>
{% endif %}
</tr>
{% endwith %}
{% endfor %}
</table>
</div>
{% endfor %}
{% else %}
<p>{% translate 'You don’t have permission to view or edit anything.' %}</p>
{% endif %}
<script type="text/javascript">
try {
let apps = JSON.parse(localStorage.getItem('apps'));
if (apps) {
let appList = document.getElementById("content-main");
// sort the divs according to the apps array
for (let i = 0; i < apps.length; i++) {
let app = apps[i];
let appDiv = document.getElementById(app);
if (appDiv) {
appList.appendChild(appDiv);
}
}
}
} catch (e) {
console.error(e);
localStorage.removeItem('apps');
}
let draggedItem = null;
const sortableList = document.getElementById("content-main");
document.querySelectorAll('[id^="django-app"]').forEach((appDiv) => {
appDiv.addEventListener('dragstart', (event) => {
draggedItem = event.target;
setTimeout(() => {
event.target.style.opacity = "50%";
}, 0);
});
appDiv.addEventListener('dragover', (event) => {
event.preventDefault();
const afterElement =
getDragAfterElement(sortableList, event.clientY);
if (afterElement == null) {
sortableList.appendChild(draggedItem)
} else {
sortableList.insertBefore(draggedItem, afterElement)
}
setTimeout(() => {
let apps = [];
for (let i = 0; i < sortableList.children.length; i++) {
if (sortableList.children[i].id) {
apps.push( sortableList.children[i].id);
}
}
localStorage.setItem('apps', JSON.stringify(apps));
}, 0);
}
);
appDiv.addEventListener('dragend', (event) => {
event.preventDefault();
setTimeout(() => {
event.target.style.opacity = "";
draggedItem = null;
}, 0);
});
});
const getDragAfterElement = (
container, y
) => {
const draggableElements = [
...container.querySelectorAll(
"div:not(.dragging)"
),];
return draggableElements.reduce(
(closest, child) => {
const box =
child.getBoundingClientRect();
const offset =
y - box.top - box.height / 2;
if (
offset < 0 &&
offset > closest.offset) {
return {
offset: offset,
element: child,
};
} else {
return closest;
}
},
{
offset: Number.NEGATIVE_INFINITY,
}
).element;
};
</script>

You can add this file to your tamplates/admin/app_list.html and make your django admin customizable by the user.

It will store the result in the local storage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment