各位用户为了找寻关于Python中Django 后台自定义表单控件的资料费劲了很多周折。这里教程网为您整理了关于Python中Django 后台自定义表单控件的相关资料,仅供查阅,以下为您介绍关于Python中Django 后台自定义表单控件的详细内容
在 django 中我们可以在 admin.py
中添加 ModelAdmin
,这样就能很方便地在后台进行增删改查的操作。然而,对应 Model
生成的表单,并不友好,我们希望能像前端开发一样做出各种类型的控件,这就得对其后台的表单进行自定义。
其实 django 已经为我们提供了一些可用的表单控件,比如:多选框、单选按钮等,下面就以单选按钮为例:
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22# forms.py
from
django
import
forms
from
.models
import
MyModel
class
MyForm(forms.ModelForm):
xxx
=
forms.ChoiceField(choices
=
[...], widget
=
forms.RadioSelect())
class
Meta:
model
=
MyModel
fields
=
[
'id'
,
'xxx'
]
# admin.py
from
django.contrib
import
admin
from
.models
import
MyModel
from
.forms
import
MyForm
class
MyAdmin(admin.ModelAdmin):
form
=
MyForm
# ...省略若干代码
admin.site.register(MyModel, MyAdmin)
先自定义一个 MyForm
,在里面为字段添加控件,widget
用来指定控件的类型,choices
指定可选列表,再在 MyAdmin
中的 form 指定为自定义表单即可。
在 django 中已经提供了很多 widget(控件),然而这些还远远满足不了我们的需求,这就需要我们去自定义,下面就以一个 ACE 插件 (ACE 是一个独立的 JavaScript 编写的基于 Web 的代码编辑器)为例,说说怎么自定义 widget:
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63#coding: utf-8
from
django
import
forms
from
django.utils.html
import
format_html
from
django.forms.utils
import
flatatt
from
django.utils.encoding
import
force_text
from
django.utils.safestring
import
mark_safe
ACE_RENDER
=
'''
<script src="/static/js/jquery-1.11.2.min.js"></script>
<script src="/static/js/ace/ace.js"></script>
<script>
$(function () {
var textarea = $('textarea');
var editDiv = $('<div>', {
position: 'absolute',
width: textarea.width(),
height: textarea.height(),
'class': textarea.attr('class')
}).insertBefore(textarea);
textarea.css('display', 'none');
var editor = ace.edit(editDiv[0]);
editor.getSession().setValue(textarea.val());
editor.getSession().setMode("ace/mode/%s");
editor.setTheme("ace/theme/%s");
textarea.closest('form').submit(function () {
textarea.val(editor.getSession().getValue());
});
});
</script>
'''
class
AceWidget(forms.Textarea):
def
__init__(
self
, mode
=
"
", theme="
", attrs
=
None
):
'''
为了能在调用的时候自定义代码类型和样式
:param mode:
:param theme:
:param attrs:
:return:
'''
super
(AceWidget,
self
).__init__(attrs)
self
.mode
=
mode
self
.theme
=
theme
def
render(
self
, name, value, attrs
=
None
):
'''
关键方法
:param name:
:param value:
:param attrs:
:return:
'''
if
value
is
None
:
value
=
''
final_attrs
=
self
.build_attrs(attrs, name
=
name)
output
=
[format_html(
'<textarea{}>rn{}</textarea>'
, flatatt(final_attrs), force_text(value))]
current_ace_render
=
ACE_RENDER
%
(
self
.mode,
self
.theme)
output.append(current_ace_render)
return
mark_safe(
'n'
.join(output))
主要就是自定义的 widget 要继承自 django 的 widget,然后重写 render 方法,在这个方法中,对新的控件进行包装。
在 forms.py
中将自定义的控件 AceWidget
引入:
#coding: utf-8
from
django
import
forms
from
.models
import
Code
from
widgets
import
AceWidget
class
CodeForm(forms.ModelForm):
code
=
forms.CharField(label
=
'源码'
, widget
=
AceWidget(attrs
=
{
'cols'
:
'100'
,
'rows'
:
'20'
}, mode
=
"python"
, theme
=
"monokai"
))
class
Meta:
model
=
Code
fields
=
[
'title'
,
'code'
]
需要注意的是:在这里使用的 mode="python", theme="monokai"
对应的文件 mode-python.js
和 theme-monokai.js
一定要在 /static/js/ace
目录下。
效果图
附录:
models.py:
#coding:utf-8
from
django.db
import
models
class
Code(models.Model):
title
=
models.CharField(
'标题'
, max_length
=
50
, unique
=
True
)
code
=
models.TextField(
'源码'
)
class
Meta:
db_table
=
'code'
verbose_name
=
verbose_name_plural
=
'代码'
def
__unicode__(
self
):
return
self
.title
admin.py:
from
django.contrib
import
admin
from
.models
import
Code
from
.forms
import
CodeForm
class
CodeAdmin(admin.ModelAdmin):
form
=
CodeForm
list_display
=
[
'id'
,
'title'
]
admin.site.register(Code, CodeAdmin)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://www.jianshu.com/p/2043d4a63955