Django
Amministrazione
Ricerca…
Cambia lista
Supponiamo tu abbia una semplice app myblog
con il seguente modello:
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 "lista dei cambiamenti" di Django Admin è la pagina che elenca tutti gli oggetti di un dato modello.
from django.contrib import admin
from myblog.models import Article
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
pass
Di default, userà il __str__()
(o __unicode__()
se tu su python2) del tuo modello per visualizzare il "nome" dell'oggetto. Ciò significa che se non l'hai sovrascritto, vedrai un elenco di articoli, tutti denominati "Articolo oggetto". Per modificare questo comportamento, puoi impostare il __str__()
:
class Article(models.Model):
def __str__(self):
return self.title
Ora, tutti i tuoi articoli dovrebbero avere un nome diverso e più esplicito di "Articolo oggetto".
Tuttavia potresti voler visualizzare altri dati in questo elenco. Per questo, usa list_display
:
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['__str__', 'author', 'date_published', 'is_draft']
list_display
non è limitato ai campi e alle proprietà del modello. può anche essere un metodo di 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'
Ulteriori stili CSS e script JS per la pagina di amministrazione
Supponiamo di avere un semplice modello Customer
:
class Customer(models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
is_premium = models.BooleanField(default=False)
Si registra in admin Django e aggiungere campo di ricerca per first_name
e last_name
:
@admin.register(Customer)
class CustomerAdmin(admin.ModelAdmin):
list_display = ['first_name', 'last_name', 'is_premium']
search_fields = ['first_name', 'last_name']
Dopo aver effettuato questa operazione, i campi di ricerca vengono visualizzati nella pagina dell'elenco di amministratori con il segnaposto predefinito: " parola chiave ". Ma cosa succede se si desidera modificare quel segnaposto su " Cerca per nome "?
Puoi farlo passando il file Javascript personalizzato in 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', )
Puoi utilizzare la barra degli strumenti debug del browser per trovare l'ID o la classe Django impostati su questa barra di ricerca e quindi scrivere il tuo codice js:
$(function () {
$('#searchbar').attr('placeholder', 'Search by name')
})
Anche la classe Media
ti consente di aggiungere file css con l'oggetto dizionario:
class Media:
css = {
'all': ('css/admin/styles.css',)
}
Ad esempio, è necessario visualizzare ogni elemento della colonna first_name
in un colore specifico.
Per impostazione predefinita Django crea una colonna di tabella per ogni elemento in list_display
, tutti i tag <td>
avranno classe css come field-'list_display_name'
, nel nostro caso sarà field_first_name
.field_first_name {
background-color: #e6f2ff;
}
Se vuoi personalizzare altri comportamenti aggiungendo JS o alcuni stili css, puoi sempre controllare id e classi di elementi nello strumento di debug del browser.
Gestione di chiavi esterne che fanno riferimento a tabelle di grandi dimensioni
Per impostazione predefinita, Django ForeignKey
rendering ForeignKey
campi ForeignKey
come input <select>
. Ciò può causare il caricamento molto lento delle pagine se nella tabella di riferimento sono presenti migliaia o decine di migliaia di voci. E anche se hai solo centinaia di voci, è abbastanza scomodo cercare una voce particolare tra tutte.
Un modulo esterno molto utile per questo è django-autocomplete-light (DAL). Ciò consente di utilizzare i campi di completamento automatico invece dei campi <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