Django admin 模型选项(ModelAdmin) 【简要】查看 |
定义一个模型DataBaseA,其中包含一个字符字段A,A有两用取值 y
与n
# models.py
class DataBaseA(models.Model):
A = models.CharField(max_length=50, choices=[('y', 'yes'), ('n', 'no')])
def __str__(self):
return self.A
为amdin页面添加一个批量操作 “将选择的内容改为y”
# admin.py
from django.contrib import admin
from .models import DataBaseA
def make_data(modeladmin, request, queryset):
queryset.update(A='y')
make_data.short_description = "将选择的内容改为y"
class DataBaseAdminA(admin.ModelAdmin):
actions = [make_data]
admin.site.register(DataBaseA, DataBaseAdminA)
默认actions_on_top = True; actions_on_bottom = False
,其操作栏位于数据库列表上方
actions_on_top = False
actions_on_bottom = True
编写代码后展示如下
如果只设置actions_on_bottom = True
,那么操作栏将在列表上方和下方同时显示;同样,你也可以是它在上方或下方都不显示。
默认情况下,操作了旁边显示列表总数与已选择的数目,如果将此属性设置为False
将不显示
DateField
或DateTimeField
字段基于日期的分层筛选导航为DataBaseA
添加一个日期字段 B
,设置此属性的值为字段B
,将为当前模型建立一个基于此日期字段的筛选导航
list_display = ('A', 'B')
date_hierarchy = 'B'
添加一个字符字段C
并设置其允许为空,如果记录该字段内容为空是设置该属性进行显示一个其他值,默认为-
empty_value_display = "空"
exclude = ('B',)
此属性设置后在添加数据页面不显示其设置的字段,不显示的字段将被编辑为空。
fields 决定对表进行编辑时展示哪些字段
fields = ('A', 'C')
fields = (('A', 'B'), 'C')
fieldsets
是一个二元组列表,其中每个二元组代表管理表单页面上的
, 这两个元组的格式为(name,field_options)
,其中name
是代表字段集标题的字符串,field_options
是有关字段集的信息词典,包括要在其中显示的字段的列表field_options
字典可以具有以下键
键 | 值 |
---|---|
fields |
要在此字段集中显示的字段名称的元组。此键是必需的 |
classes |
包含要应用于该字段集的额外CSS类的列表或元组 |
description |
一串可选的额外文本,将显示在每个字段集顶部,字段集标题下; 默认样式collapse和wide。 collapse样式的字段集将折叠,并替换为一个小的“单击以展开”链接。 wide样式的字段集将获得额外的水平空间。 |
fieldsets = (('内容1', {'fields': ('A', 'B'),
'classes': ('wide',)}),
('内容2', {'fields': ('C',),
'classes': ('collapse',),
'description': '这是额外的描述信息'}))
为模型DataBaseA
添加一个多对对字段D
,关联到新创建模型DataBaseB
,DataBaseB
内含有有个字符字段X
;
# models.py
from django.db import models
class DataBaseA(models.Model):
A = models.CharField(max_length=50, choices=[('y', 'yes'), ('n', 'no')])
B = models.DateField(blank=True, null=True)
C = models.CharField(max_length=50, blank=True, null=True)
D = models.ManyToManyField('DataBaseB', blank=True)
def __str__(self):
return self.A
class DataBaseB(models.Model):
X = models.CharField(max_length=50)
def __str__(self):
return self.X
默认视图
设置此属性为多对多字段,为该字段添加一个水平过滤器
filter_horizontal = ('D',)
当设置 filter_vertical = ('D',)
后显示为垂直过滤器
给字段C增加一个验证,让其只能接收四位数字
from django.contrib import admin
from .models import DataBaseA
from django import forms
def validate(value): # 验证数据
try:
v = int(value)
except:
raise forms.ValidationError(u'输入四位数字')
if len(value) != 4:
raise forms.ValidationError(u'输入四位数字')
class MyForm(forms.ModelForm):
code = forms.CharField(validators=[validate], widget=forms.TextInput(attrs={'placeholder': u'输入四位数字填充字段C'}))
class Meta: # 不展示字段C
exclude = ['C']
class DataBaseAdminA(admin.ModelAdmin):
list_display = ('A', 'C')
form = MyForm
def save_model(self, request, obj, form, change): # 自定义save_model()给字段C填充数据
code = request.POST.get('code')
obj.C = code
obj.save()
admin.site.register(DataBaseA, DataBaseAdminA)
将默认TextField字段的文本框改小一点
from django.contrib import admin
from .models import DataBaseA
from django.db import models
from django.forms import Textarea
class DataBaseAdminA(admin.ModelAdmin):
list_display = ('A', 'C', 'E')
formfield_overrides = {
models.TextField: {'widget': Textarea(attrs={'rows': 2, 'cols': 25})},
}
admin.site.register(DataBaseA, DataBaseAdminA)
from django.contrib import admin
from django.db import models
# Import our custom widget and our model from where they're defined
from myapp.models import MyModel
from myapp.widgets import RichTextEditorWidget
class MyModelAdmin(admin.ModelAdmin):
formfield_overrides = {
models.TextField: {'widget': RichTextEditorWidget},
}
DataBaseA 和 DataBaseB 是一对多关系,在模型DataBaseA中内联DataBaseB,将其内容添加到DataBaseA进行动态编辑
# models.py
from django.db import models
class DataBaseA(models.Model):
A = models.CharField(max_length=100)
def __str__(self):
return self.A
class DataBaseB(models.Model):
X = models.ForeignKey(DataBaseA, on_delete=models.CASCADE)
Y = models.CharField(max_length=100)
def __str__(self):
return self.Y
# admin.py
class DataBaseAdminB(admin.TabularInline):
model = DataBaseB
extra = 1 # 默认为3
class DataBaseAdminA(admin.ModelAdmin):
inlines = [DataBaseAdminB]
admin.site.register(DataBaseA, DataBaseAdminA)
admin.site.register(DataBaseB)
Django提供了InlineModelAdmin的两个子类,它们是: TabularInline
和 StackedInline
;他们略有区别
可以使用四种类型的值list_display:
list_display = ('A', 'B', 'C')
def upper_case_name(obj):
return ("%s : %s" % (obj.A, obj.B)).upper()
upper_case_name.short_description = 'A 和 B'
class DataBaseAdminA(admin.ModelAdmin):
list_display = (upper_case_name,)
class DataBaseAdminA(admin.ModelAdmin):
list_display = ('upper_case_name',)
def upper_case_name(self, obj):
return ("%s : %s" % (obj.A, obj.B)).upper()
upper_case_name.short_description = 'A 和 B'
# models.py
from django.db import models
class DataBaseA(models.Model):
D = models.DateField(blank=True, null=True)
def decade_born_in(self):
return self.D.strftime('%Y')[:4]
decade_born_in.short_description = '年'
# admin.py
from django.contrib import admin
from .models import DataBaseA
class DataBaseAdminA(admin.ModelAdmin):
list_display = ('decade_born_in', 'D')
admin.site.register(DataBaseA, DataBaseAdminA)
list_display = ('A', 'B', 'C')
list_display_links = ('C',)
list_display = ('A', 'B', 'C')
list_editable = ('B',)
list_display = ('A', 'B', 'C')
list_filter = ('B', 'C')
设置list_per_page 后 设置list_max_show_all将不起效果,可能数据量少的原因,此属性有待探究
list_per_page = 5
select_related()
在列表页面上检索对象列表时使用设置list_select_related为告诉Django select_related()在列表页面上检索对象列表时使用。这样可以为您节省大量数据库查询
该值应该是布尔值,列表或元组。默认值为False。
当值为True时,将始终调用select_related()。当值设置为False时,Django将查看list_display并调用select_related()(如果存在任何ForeignKey)
如果需要更精细的控制,请使用元组(或列表)作为list_select_related的值。空元组将完全阻止Django调用select_related()。任何其他元组将直接传递给select_related作为参数
ordering = ['B']
暂无查到关于admin分页器的内容
官方介绍:
默认情况下,使用
django.core.paginator.Paginator
。如果自定义paginator
类与django.core.paginator.Paginator
没有相同的构造函数接口,则还需要提供ModelAdmin.get_paginator()
的实现。
添加页面,当在某字段填入值后,自动会将值填充到指定字段
prepopulated_fields = {"A": ("B", "C",)}
当对字段B与C输入内容时,A字段将会自动填充B或C的内容,多个字段会使用-
来分割
详细页面,删除、修改,更新后跳转回列表后,是否保留原搜索条件,默认True
radio_fields = {"A": admin.VERTICAL}
radio_fields = {"A": admin.HORIZONTAL}
注意:此属性设置的值绑定的外键必须启用search_fields
autocomplete_fields = ['X']
raw_id_fields = ['X']
readonly_fields = ('B',)
在编辑页面将”保存并添加另一个“ 更改为“保存成新的”
save_as = True
当save_as=True,节省了新对象后的默认重定向是该对象的编辑视图。如果设置了 save_as_continue=False,重定向将转到编辑列表视图。(默认True)
在这里插入代码片
True
显示为“总共”多少; False
显示为“显示全部”
show_full_result_count = False
sortable_by = ('B', )
只让其元组内的字段参与排序 ,其余字段将不可进行排序
当在模型中有get_absolute_url()
方法,则在修改页面显示 “在站点上查看”,可以通过将view_on_site
设置为False
不显示此按钮
注:关于get_absolute_url()
请自行阅读路由反向解析
# models.py
from django.db import models
from django.urls import reverse
class DataBaseA(models.Model):
A = models.CharField(max_length=100, choices=(('a', 'A'), ('b', 'B'), ('c', 'C')))
B = models.CharField(max_length=100, blank=True, null=True)
C = models.CharField(max_length=100, blank=True, null=True)
D = models.DateField(blank=True, null=True)
def get_absolute_url(self):
return reverse('home')
在 amdin.py 中存在view_on_site()
方法也会显示此功能
class DataBaseAdminA(admin.ModelAdmin):
def view_on_site(self, obj):
url = reverse('home')
return 'http://127.0.0.1:8000' + url
list_display = ('A', 'B', 'C')
admin.site.register(DataBaseA, DataBaseAdminA)