首頁  >  文章  >  後端開發  >  實例詳解Python中Django後台自訂表單控件

實例詳解Python中Django後台自訂表單控件

Y2J
Y2J原創
2017-04-28 09:37:281859瀏覽

本篇文章主要介紹了Python中Django 後台自定義表單控件,其實 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 src="/static/js/jquery-1.11.2.min.js"></script>
<script src="/static/js/ace/ace.js"></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>
&#39;&#39;&#39;

class AceWidget(forms.Textarea):
  def __init__(self, mode="", theme="", attrs=None):
    &#39;&#39;&#39;
    为了能在调用的时候自定义代码类型和样式
    :param mode:
    :param theme:
    :param attrs:
    :return:
    &#39;&#39;&#39;
    super(AceWidget, self).__init__(attrs)
    self.mode = mode
    self.theme = theme

  def render(self, name, value, attrs=None):
    &#39;&#39;&#39;
    关键方法
    :param name:
    :param value:
    :param attrs:
    :return:
    &#39;&#39;&#39;
    if value is None:
      value = &#39;&#39;
    final_attrs = self.build_attrs(attrs, name=name)
    output = [format_html(&#39;<textarea{}>\r\n{}</textarea>&#39;, flatatt(final_attrs), force_text(value))]
    current_ace_render = ACE_RENDER %(self.mode, self.theme)
    output.append(current_ace_render)
    return mark_safe(&#39;\n&#39;.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=&#39;源码&#39;, widget=AceWidget(attrs={&#39;cols&#39;: &#39;100&#39;, &#39;rows&#39;: &#39;20&#39;}, mode="python", theme="monokai"))

  class Meta:
    model = Code
    fields = [&#39;title&#39;, &#39;code&#39;]

需要注意的是:這裡使用的 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(&#39;标题&#39;, max_length=50, unique=True)
  code = models.TextField(&#39;源码&#39;)

  class Meta:
    db_table = &#39;code&#39;
    verbose_name = verbose_name_plural = &#39;代码&#39;

  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 = [&#39;id&#39;, &#39;title&#39;]

admin.site.register(Code, CodeAdmin)

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

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn