深入了解Python中Django後台自訂表單控件

高洛峰
發布: 2017-03-31 09:56:10
原創
2090 人瀏覽過

本篇文章主要介紹了PythonDjango 後台自訂表單控制項,其實django 已經為我們提供了一些可用的表單控件,例如:多選框、單選按鈕等,有興趣的開幕了解。

在 django 中我們可以在 admin.py 中加入 ModelAdmin,這樣就能很方便地在後台進行增刪改查的操作。然而,對應 Model 產生的表單,並不友好,我們希望像前端開發一樣做出各種類型的控件,這就得對其後台的表單進行自訂。

其實django 已經為我們提供了一些可用的表單控件,例如:多選框、單選按鈕等,下面就以單選按鈕為例:

# 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:

#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></script>
<script></script>
<script>
  $(function () {
    var textarea = $(&#39;textarea&#39;);
    var editp = $(&#39;<p>&#39;, {
      position: &#39;absolute&#39;,
      width: textarea.width(),
      height: textarea.height(),
      &#39;class&#39;: textarea.attr(&#39;class&#39;)
    }).insertBefore(textarea);
    textarea.css(&#39;display&#39;, &#39;none&#39;);
    var editor = ace.edit(editp[0]);
    editor.getSession().setValue(textarea.val());
    editor.getSession().setMode("ace/mode/%s");
    editor.setTheme("ace/theme/%s");
    textarea.closest(&#39;form&#39;).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>\r\n{}</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 目錄下。

效果圖

深入了解Python中Django後台自訂表單控件

「附錄:

#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)
登入後複製

以上是深入了解Python中Django後台自訂表單控件的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板