Django
Administrering
Sök…
Ändra lista
Låt oss säga att du har en enkel myblog
app med följande modell:
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()
Django Admin "ändringslista" är sidan som visar alla objekt i en given modell.
from django.contrib import admin
from myblog.models import Article
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
pass
Som standard använder den __str__()
-metoden (eller __unicode__()
om du på python2) för din modell för att visa objektet "namn". Detta innebär att om du inte åsidosätter det kommer du att se en lista med artiklar, alla kallade "Artikelobjekt". För att ändra detta beteende kan du ställa in __str__()
:
class Article(models.Model):
def __str__(self):
return self.title
Nu bör alla dina artiklar ha ett annat namn och mer tydligt än "Artikelobjekt".
Men du kanske vill visa andra data i den här listan. list_display
:
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['__str__', 'author', 'date_published', 'is_draft']
list_display
är inte begränsat till list_display
och egenskaper. det kan också vara en metod för din 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'
Ytterligare CSS-stilar och JS-skript för admin sida
Anta att du har en enkel 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)
Du registrerar det i Django-administratören och lägger till first_name
efter first_name
och last_name
:
@admin.register(Customer)
class CustomerAdmin(admin.ModelAdmin):
list_display = ['first_name', 'last_name', 'is_premium']
search_fields = ['first_name', 'last_name']
När du har gjort detta visas sökfälten på adminlistasidan med standardplatshållaren: " nyckelord ". Men tänk om du vill ändra denna platshållare till " Sök efter namn "?
Du kan göra detta genom att skicka anpassad Javascript-fil till 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', )
Du kan använda verktygsfältet för felsökning för webbläsare för att hitta vilken id eller klass Django som ställs in i det här sökfältet och sedan skriva din js-kod:
$(function () {
$('#searchbar').attr('placeholder', 'Search by name')
})
Även Media
klass kan du lägga till CSS-filer med ordlistan objekt:
class Media:
css = {
'all': ('css/admin/styles.css',)
}
Vi måste till exempel visa varje element i first_name
kolumnen i specifik färg.
Som standard skapar Django tabellkolumn för varje objekt i list_display
, alla <td>
-taggar har css-klass som field-'list_display_name'
, i vårt fall kommer det field_first_name
.field_first_name {
background-color: #e6f2ff;
}
Om du vill anpassa annat beteende genom att lägga till JS eller några css-stilar, kan du alltid kontrollera ID: s och klasser av element i webbläsarens felsökningsverktyg.
Hantera utländska nycklar som hänvisar till stora bord
Som standard ForeignKey
Django ForeignKey
fält som en <select>
-ingång. Detta kan göra att sidor laddas riktigt långsamt om du har tusentals eller tiotusentals poster i den refererade tabellen. Och även om du bara har hundratals poster är det ganska obekvämt att leta efter en viss post bland alla.
En mycket praktisk extern modul för detta är django-autocomplete-light (DAL). Detta gör det möjligt att använda autofyllt fält istället för fält <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