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> .

Ejemplo django-autocomplete-light

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


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow