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

esempio di django-autocomplete-light

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


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow