Django
Administración
Buscar..
Lista de cambios
Digamos que tienes una aplicación de myblog
simple con el siguiente modelo:
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 de cambios" de Django Admin es la página que lista todos los objetos de un modelo dado.
from django.contrib import admin
from myblog.models import Article
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
pass
Por defecto, utilizará el __str__()
(o __unicode__()
si está en python2) de su modelo para mostrar el "nombre" del objeto. Esto significa que si no lo ha anulado, verá una lista de artículos, todos llamados "Objeto de artículo". Para cambiar este comportamiento, puede configurar el __str__()
:
class Article(models.Model):
def __str__(self):
return self.title
Ahora, todos sus artículos deben tener un nombre diferente y más explícito que "Objeto de artículo".
Sin embargo, es posible que desee mostrar otros datos en esta lista. Para esto, usa list_display
:
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['__str__', 'author', 'date_published', 'is_draft']
list_display
no está limitado a los campos y propiedades del modelo. También puede ser un método de su 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'
Estilos CSS adicionales y scripts JS para la página de administración
Supongamos que tiene un modelo de 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)
Se registra en la administración de Django y añadir campo de búsqueda por first_name
y last_name
:
@admin.register(Customer)
class CustomerAdmin(admin.ModelAdmin):
list_display = ['first_name', 'last_name', 'is_premium']
search_fields = ['first_name', 'last_name']
Después de hacer esto, los campos de búsqueda aparecen en la página de la lista de administradores con el marcador de posición predeterminado: " palabra clave ". ¿Pero qué sucede si desea cambiar ese marcador de posición a " Buscar por nombre "?
Puede hacerlo pasando un archivo Javascript personalizado a los Media
administración:
@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', )
Puede usar la barra de herramientas de depuración del navegador para encontrar qué ID o clase Django estableció en esta barra de búsqueda y luego escribir su código js:
$(function () {
$('#searchbar').attr('placeholder', 'Search by name')
})
También la clase Media
permite agregar archivos css con objeto de diccionario:
class Media:
css = {
'all': ('css/admin/styles.css',)
}
Por ejemplo, necesitamos mostrar cada elemento de la columna first_name
en un color específico.
Por defecto, Django crea una columna en la tabla para cada elemento en list_display
, todas las etiquetas <td>
tendrán una clase css como el field-'list_display_name'
, en nuestro caso será field_first_name
.field_first_name {
background-color: #e6f2ff;
}
Si desea personalizar otro comportamiento agregando JS o algunos estilos css, siempre puede verificar los ID y las clases de elementos en la herramienta de depuración del navegador.
Manejo de claves foráneas que hacen referencia a tablas grandes.
De forma predeterminada, Django presenta los campos de ForeignKey
como una entrada de <select>
. Esto puede hacer que las páginas se carguen muy lentamente si tiene miles o decenas de miles de entradas en la tabla a la que se hace referencia. E incluso si tiene solo cientos de entradas, es bastante incómodo buscar una entrada en particular entre todas.
Un módulo externo muy útil para esto es django-autocomplete-light (DAL). Esto permite utilizar los campos de autocompletar en lugar de los campos de <select>
.
vistas.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