1. pip install Django-suit
2. 将’suit’加到INSTALLED_APPS中,suit 必须在所有管理APP之前。
3. 将django.template.context_processors.request 加到TEMPLATES->OPTIONS->context_processors设置中,用于左侧的menu菜单的处理。
4. 部署见Djangodocs on wsgi。
1. 模板文件base_site.html需要拷到任意的模板路径中(tempaltes/admin/ 或TEMPLATE_DIRS设置中)
2. 例子见github
3. 自定义模板DjangoAdmin Tutorial
# 配置的默认选项和解释如下
1. SUIT_CONFIG = {
2. # header 网页头部显示选项
3. # 'ADMIN_NAME': 'Django Suit', 左侧标题
4. # 'HEADER_DATE_FORMAT': 'l, j. F Y', 日期格式见Django日期格式说明
5. # 'HEADER_TIME_FORMAT': 'H:i',
6.
7. # forms 表单相关
8. # 'SHOW_REQUIRED_ASTERISK': True, # Default True 必填的表单项显示星号
9. # 'CONFIRM_UNSAVED_CHANGES': True, # Default True 未保存时提示是否保存
10.
11. # menu 左侧菜单相关
12. # 'SEARCH_URL': '/admin/auth/user/', 搜索时默认的url
13. # 'MENU_ICONS': {
14. # 'sites': 'icon-leaf', 暂不明确
15. # 'auth': 'icon-lock',
16. # },
17. # 'MENU_OPEN_FIRST_CHILD': True, # Default True 点击菜单时打开其第一个子菜单
18. # 'MENU_EXCLUDE': ('auth.group',), 将app或其model不在menu菜单中显示
19. # 'MENU': (
20. # 'sites', 暂不明确
21. # {'app': 'auth', 'icon':'icon-lock', 'models': ('user', 'group')}, 验证app
22. # {'label': 'Settings', 'icon':'icon-cog', 'models': ('auth.user', 'auth.group')} 自定义app,设置其菜单名,图标,所包含的models,或只是一个链接
23. # {'label': 'Support', 'icon':'icon-question-sign', 'url': '/support/'},
24. # ),
25.
26. # misc
27. # 'LIST_PER_PAGE': 15 changelist每页显示的最大条目数
相关的类:class model, class ModelForm, class ModelAdmin
这里建立Country 菜单项为例,展示如何在管理控制台中添加相应的控制页面。
step1:建立数据模型 model.py
1. class Country(models.Model):
2. name = models.CharField(max_length=256)
3. code = models.CharField(max_length=2,
4. help_text='ISO 3166-1 alpha-2 - two character '
5. 'country code')
6. independence_day = models.DateField(blank=True, null=True)
7. continent = models.ForeignKey(Continent, null=True)
8. area = models.BigIntegerField(blank=True, null=True)
9. population = models.BigIntegerField(blank=True, null=True)
10. order = models.PositiveIntegerField(default=0)
11. description = models.TextField(blank=True,
12. help_text='Try and enter few some more '
13. 'lines')
14. architecture = models.TextField(blank=True)
15.
16. def __unicode__(self):
17. return self.name
step2:建立模型表单类 admin.py:
1. class CountryForm(ModelForm):
2. class Meta:
3. #指定form对应的model
4. model=Country
5. #指定要显示的字段
6. #全部指定
7. fields= '__all__'
8. #部分指定
9. #fields=['name','code','continent','population']
step3:建立模型管理类 admin.py:
1. class CountryAdmin(ModelAdmin):
2. form = CountryForm
step4:注册模型和模型管理类admin.py:
1. admin.site.register(Country,CountryAdmin)
在setting.py INSTALLED_APPS中添加app后,在SUIT_CONFIG的‘menu’中添加: {'label': 'Country', 'app': 'django_suit_test', 'models': ('Country',)},
1. 'MENU': (
2.
3. # Keep original label and models
4. 'sites',
5.
6. # Country app
7. {'label': 'Country', 'app': 'django_suit_test', 'models': ('Country',)},
8. ),
在对应的ContryForm类中添加widgets
1. class CountryForm(ModelForm):
2. class Meta:
3. # 指定form对应的model
4. model = Country
5. # 指定要显示的字段
6. # 全部指定
7. fields = '__all__'
8. # 部分指定
9. # fields=['name','code','continent','population']
10. # widgets
11. widgets = {
12.
13. }
1、TextInput:文本
2、NumberInput:数值
3、EnclosedInput:前后可加图标或按钮修饰
4、SuitDateWidget:日期
5、任意html5输入类型:HTML5Input(input_type='number')
6、可在在输入类型中添加boostrap类进行修饰
1. class CountryForm(ModelForm):
2. class Meta:
3. widgets = {
4. # attrs 添加bootstrap类属性
5. #
6. 'code': TextInput(attrs={'class': 'input-mini'}),
7. #
8. 'order': NumberInput(attrs={'class': 'input-mini'}),
9. # EnclosedInput 在前后加图标、按钮等
10. 'area': EnclosedInput(prepend='icon-globe', append='km2',
11. attrs={'class': 'input-small'}),
12. 'population': EnclosedInput(prepend='icon-user',
13. append='
14. 'class="btn" οnclick="window'
15. '.open(\'https://www.google'
16. '.com/\')" value="Search">',
17. attrs={'class': 'input-small'}),
18. # AutosizedTextarea 自动大小的文本域,可加任何的属性
19. 'description': AutosizedTextarea(attrs={'class': 'span3'}),
20. # Date / Time widgets 日期
21. 'independence_day': SuitDateWidget,
22.
23. }
在Country模型中加入order=model.PositiveInteger()字段后,并在其表单管理中加入sorable=’order’即可实现在表单显示出现order可实现字段的移动。
1. class CountryAdmin(SortableModelAdmin):
2.
3. #sortable
4. sortable = 'order'
同理可以实现以tabular_inline,stacked_inline 形式的表单显示方式,
区别在于CountryAdmin分别继承至SortableTabularInline,和SortableStackedInline。
Form tabs:
表单修改tabs显示:
1. from django.contrib import admin
2. from .models import Country
4.
5. class CityInline(admin.TabularInline):
6. model = City
7. suit_classes = 'suit-tab suit-tab-cities' #在tabs中显示的inline对象要加该行
8.
9.
10. class CountryAdmin(admin.ModelAdmin):
11. inlines = (CityInline,)
12. #表单字段的分类显示
13. fieldsets = [
14. (None, {
15. #在tab中显示的话要加’classes:(‘suit-tab’,’suit-tab-
16. 'classes': ('suit-tab', 'suit-tab-general',),
17. 'fields': ['name', 'continent',]
18. }),
19. ('Statistics', {
20. 'classes': ('suit-tab', 'suit-tab-general',),
21. 'fields': ['area', 'population']}),
22. ('Architecture', {
23. 'classes': ('suit-tab', 'suit-tab-cities',),
24. 'fields': ['architecture']}),
25. ]
26. #下行中的tuple含义是(tabname,tabtitle)
27. suit_form_tabs = (('general', 'General'), ('cities', 'Cities'),
28. ('info', 'Info on tabs'))
29.
30. #可以在tab页中在fieldset和inline中插入而外的html对象,方位可选 top,middle,bottom
31. suit_form_includes = (
32. ('admin/examples/country/custom_include.html', 'middle', 'cities'),
33. )
34. admin.site.register(Country, CountryAdmin)
行颜色显示
1. def suit_row_attributes(self, obj):
2. class_map = {
3. 'Europe': 'success',
4. 'South America': 'warning',
5. 'North America': 'success',
6. 'Africa': 'error',
7. 'Australia': 'warning',
8. 'Asia': 'info',
9. 'Antarctica': 'info',
10. }
11.
12. css_class = class_map.get(obj.name)
13. if css_class:
14. return {'class': css_class}
单元格文本居中
1. class CountryAdmin(ModelAdmin):
2. ...
3.
4. def suit_cell_attributes(self, obj, column):
5. if column == 'countries':
6. return {'class': 'text-center'}
7. elif column == 'name' and obj.status == -1:
8. return {'class': 'text-error'}
实现:修改模板base_site.html
实现:
1. class industryCategoryAdmin(admin.ModelAdmin):
2. # 定义在添加项时,需要添加的条目和顺序。
3. fields = ('name', 'name_zh')
4. # 定义在显示列表中需要显示的条目。
5. list_display = ('name', 'name_zh', 'query_second_category', )
6. # 显示一个超链接按钮
7. def query_second_category(self, obj):
8. return "查看二级行业" % obj.name_zh
9. query_second_category.allow_tags = True
10. query_second_category.short_description = "操作" #超链接按钮的标题。
其中id_introduction是id_<字段名>
1. {% block extrajs %}
2. {{ block.super }}
3.
4.
5.
6.
7.
10. {% endblock %}
在model中定义的meta加入如下字段,verbose_name表示一条记录的名字,verbose_name_plural表示多条记录的名字。
1. class meta:
2. verbose_name=
3. verbose_name_plural=
list_filter =(('upper__name_zh', methods.custom_titled_filter('所属一级行业')),)
clean()是祖先类BaseForm的方法,在对表单验证时会被间接调用,可通过重写该方法进一步对表单验证,当然也可以重写is_validate()
1. class userinfoForm(forms.ModelForm):
2. class Meta:
3. model = models.userinfo
4. widgets = {
5. # 添加本条是为了不让浏览器自动填充用户名、密码。
6. 'password': forms.PasswordInput(attrs={'autocomplete': 'new-password', 'class': 'form-control'},
7. render_value=True),
8. }
9. fields = ('password', 'mobile')
10.
11. # 在这里对密码长度和手机号长度做限制。这个判定方法有些简单,后期有必要的话应做更详细的判定。
12. def clean(self):
13. super(userinfoForm, self).clean()
14. password = self.cleaned_data.get('password')
15. mobile = self.cleaned_data.get('mobile')
16. if len(str(password)) < 6:
17. if not len(str(password)) == 0:
18. raise forms.ValidationError("密码太短,请至少输入6位密码。")
19. if len(str(mobile)) < 11:
20. if not len(str(mobile)) == 0:
21. raise forms.ValidationError("手机号码填写不正确")
22. return self.cleaned_data
是在表单提交时调用的方法,可对其进行重写改变数据的存储,如密码加密等。
是显示表单时调用的函数,返回表单对象,可对其进行重写,改变表单的显示内容。
1. def save_model(self, request, obj, form, change):
2. methods = public_methods()
3. str_brief = str(obj.brief)
4. obj.brief = methods.ueditor_imgsrc_replace(str_brief)
5. str_introduction = str(obj.introduction)
6. obj.introduction = methods.ueditor_imgsrc_replace(str_introduction)
7. obj.save()
8.
9. def get_form(self, request, obj=None, **kwargs):
10. if not obj is None:
11. methods = public_methods()
12. str_brief = str(obj.brief)
13. obj.brief = methods.ueditor_imgsrc_disreplace(str_brief)
14. str_introduction = str(obj.introduction)
15. obj.introduction = methods.ueditor_imgsrc_disreplace(str_introduction)
16. form = super(platformAdmin, self).get_form(request, obj, **kwargs)
17. return form
用models的FileField和 ImageField