Django
Administration
Recherche…
Changer de liste
Disons que vous avez une application myblog
simple avec le modèle suivant:
from django.conf import settings
from django.utils import timezone
class Article(models.Model):
title = models.CharField(max_length=70)
slug = models.SlugField(max_length=70, unique=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, models.PROTECT)
date_published = models.DateTimeField(default=timezone.now)
is_draft = models.BooleanField(default=True)
content = models.TextField()
La liste de changement de Django Admin est la page qui répertorie tous les objets d'un modèle donné.
from django.contrib import admin
from myblog.models import Article
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
pass
Par défaut, il utilisera la __str__()
(ou __unicode__()
si vous êtes sur python2) de votre modèle pour afficher l'objet "name". Cela signifie que si vous ne le remplacez pas, vous verrez une liste d'articles, tous nommés "Objet article". Pour modifier ce comportement, vous pouvez définir la __str__()
:
class Article(models.Model):
def __str__(self):
return self.title
Maintenant, tous vos articles doivent avoir un nom différent et plus explicite que "Objet article".
Cependant, vous souhaiterez peut-être afficher d'autres données dans cette liste. Pour cela, utilisez list_display
:
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['__str__', 'author', 'date_published', 'is_draft']
list_display
n'est pas limité aux champs et propriétés du modèle. cela peut aussi être une méthode de votre ModelAdmin
:
from django.forms.utils import flatatt
from django.urls import reverse
from django.utils.html import format_html
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'author_link', 'date_published', 'is_draft']
def author_link(self, obj):
author = obj.author
opts = author._meta
route = '{}_{}_change'.format(opts.app_label, opts.model_name)
author_edit_url = reverse(route, args=[author.pk])
return format_html(
'<a{}>{}</a>', flatatt({'href': author_edit_url}), author.first_name)
# Set the column name in the change list
author_link.short_description = "Author"
# Set the field to use when ordering using this column
author_link.admin_order_field = 'author__firstname'
Styles CSS et scripts JS supplémentaires pour la page d'administration
Supposons que vous ayez un modèle Customer
simple:
class Customer(models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
is_premium = models.BooleanField(default=False)
Vous l'enregistrez dans l'administrateur de Django et ajoutez un champ de recherche par first_name
et last_name
:
@admin.register(Customer)
class CustomerAdmin(admin.ModelAdmin):
list_display = ['first_name', 'last_name', 'is_premium']
search_fields = ['first_name', 'last_name']
Après cela, les champs de recherche apparaissent dans la page de la liste des administrateurs avec l'espace réservé par défaut: " mot-clé ". Mais que se passe-t-il si vous souhaitez remplacer cet espace réservé par " Rechercher par nom "?
Vous pouvez le faire en transmettant un fichier Javascript personnalisé dans admin Media
:
@admin.register(Customer)
class CustomerAdmin(admin.ModelAdmin):
list_display = ['first_name', 'last_name', 'is_premium']
search_fields = ['first_name', 'last_name']
class Media:
#this path may be any you want,
#just put it in your static folder
js = ('js/admin/placeholder.js', )
Vous pouvez utiliser la barre d'outils de débogage du navigateur pour trouver l'id ou la classe Django définie sur cette barre de recherche, puis écrire votre code js:
$(function () {
$('#searchbar').attr('placeholder', 'Search by name')
})
De plus, la classe Media
vous permet d'ajouter des fichiers CSS avec un objet dictionnaire:
class Media:
css = {
'all': ('css/admin/styles.css',)
}
Par exemple, nous devons afficher chaque élément de la colonne first_name
dans une couleur spécifique.
Par défaut, la colonne create table de Django pour chaque élément de list_display
, toutes les balises <td>
auront la classe css comme field-'list_display_name'
, dans notre cas il s'agira de field_first_name
.field_first_name {
background-color: #e6f2ff;
}
Si vous souhaitez personnaliser d'autres comportements en ajoutant JS ou certains styles css, vous pouvez toujours vérifier les identifiants et les classes d'éléments dans l'outil de débogage du navigateur.
Traiter des clés étrangères référençant de grandes tables
Par défaut, Django rend les champs ForeignKey
comme une entrée <select>
. Cela peut entraîner un chargement très lent des pages si vous avez des milliers ou des dizaines de milliers d'entrées dans la table référencée. Et même si vous n’avez que des centaines d’entrées, il est très difficile de rechercher une entrée particulière parmi toutes.
Un module externe très pratique pour cela est django-autocomplete-light (DAL). Cela permet d'utiliser des champs de saisie semi-automatique au lieu des champs <select>
.
views.py
from dal import autocomplete
class CityAutocomp(autocomplete.Select2QuerySetView):
def get_queryset(self):
qs = City.objects.all()
if self.q:
qs = qs.filter(name__istartswith=self.q)
return qs
urls.py
urlpatterns = [
url(r'^city-autocomp/$', CityAutocomp.as_view(), name='city-autocomp'),
]
forms.py
from dal import autocomplete
class PlaceForm(forms.ModelForm):
city = forms.ModelChoiceField(
queryset=City.objects.all(),
widget=autocomplete.ModelSelect2(url='city-autocomp')
)
class Meta:
model = Place
fields = ['__all__']
admin.py
@admin.register(Place)
class PlaceAdmin(admin.ModelAdmin):
form = PlaceForm