Django
管理
サーチ…
変更リスト
次のモデルの単純なmyblog
アプリがあるとしましょう:
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の「変更リスト」は、特定のモデルのすべてのオブジェクトをリストするページです。
from django.contrib import admin
from myblog.models import Article
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
pass
デフォルトでは、オブジェクトの名前を表示するために、モデルの__str__()
メソッド(またはPython2の場合は__unicode__()
unicode __unicode__()
)を使用します。これは、あなたがそれを上書きしなければ、すべての記事オブジェクトという名前の記事リストを見ることを意味します。この動作を変更するには、 __str__()
メソッドを設定します。
class Article(models.Model):
def __str__(self):
return self.title
さて、あなたのすべての記事は、別の名前を持つ必要がありますし、 "記事オブジェクト"よりも明示的です。
ただし、このリストに他のデータを表示することもできます。そのためには、 list_display
:
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['__str__', 'author', 'date_published', 'is_draft']
list_display
は、モデルフィールドとプロパティに限定されません。あなたの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'
管理ページ用の追加のCSSスタイルとJSスクリプト
シンプルな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)
Django管理者に登録し、検索フィールドをfirst_name
とlast_name
追加します:
@admin.register(Customer)
class CustomerAdmin(admin.ModelAdmin):
list_display = ['first_name', 'last_name', 'is_premium']
search_fields = ['first_name', 'last_name']
これを実行すると、検索フィールドが管理者リストページに表示され、デフォルトのプレースホルダ: " キーワード "が表示されます。しかし、そのプレースホルダを「 名前で検索 」に変更したい場合はどうすればよいでしょうか?
カスタムJavascriptファイルを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', )
ブラウザデバッグツールバーを使用して、Djangoがこの検索バーに設定したIDまたはクラスを見つけて、jsコードを書くことができます:
$(function () {
$('#searchbar').attr('placeholder', 'Search by name')
})
Media
クラスでは、辞書オブジェクトを含むCSSファイルを追加することもできます:
class Media:
css = {
'all': ('css/admin/styles.css',)
}
たとえば、 first_name
列の各要素を特定の色で表示する必要があります。
デフォルトでは、Djangoはlist_display
各項目のテーブル列を作成し、すべての<td>
タグはfield-'list_display_name'
ようなcssクラスを持ちますが、この場合はfield_first_name
.field_first_name {
background-color: #e6f2ff;
}
JSやいくつかのCSSスタイルを追加して他の動作をカスタマイズしたい場合は、ブラウザのデバッグツールでidとコンポーネントのクラスをチェックすることができます。
大きなテーブルを参照する外部キーの処理
デフォルトでは、DjangoはForeignKey
フィールドを<select>
入力としてレンダリングします。これは、参照されるテーブルに何千も何千ものエントリがあると、ページのロードが非常に遅くなる可能性があります。数百のエントリしかない場合でも、すべてのエントリの中から特定のエントリを探すのは非常に不愉快です。
これのための非常に便利な外部モジュールはdjango-autocomplete-light (DAL)です。これにより、 <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