Django之Form、ModelForm 組件

1、Form組件:

django框架提供了一個form類,來處理web開發中的表單相關事項。衆所周知,form最常作的是對用戶輸入的內容進行驗證,爲此django的forms類提供了全面的內容驗證和保留用戶上次輸入數據的支持。php

 form組件有2大大功能css

對用戶提交的內容進行驗證(form表單/Ajax)html

保留用戶上次輸入的內容前端

 

一、對用戶提交的數據進行驗證python

form組件驗證的原理web

 

1.obj=Form()form組件類實例化時找到類中全部的字段 把這些字段 變成組合成字典;ajax

self.fields={‘user’:正則表達式1,‘pwd’:正則表達式2}正則表達式

2.循環self.fields字典(本身寫的字段)數據庫

for  k,v  in self.fields.items():django

    K是user,pwd

   v是正則表達式

3.每次循環經過self.fields字典的鍵, 一個一個的去get前端POST提交的數據 獲得用戶輸入數據;

input_value= request.post.get(‘k’)(因此form字段的名稱,要和前端的name屬性匹配)

4.每次拿到用戶輸入的數據 (input_value)和進行正則表達式匹配;

5.匹配成功flag=True 匹配失敗flag=falsh,最後 return flag  obj.is_valid=flag。

若是For自帶的規則和正則知足不了驗證需求,可在Form類中自定義方法,作擴展。

6.每一個字段驗證經過後,每一個字段執執行self.clean_filelds函數(自定義 對Form類中的字段作單獨驗證,好比去數據庫查詢判斷一下用戶提交的數據是否存在?)

7. 執行Form組件的clean_form方法進行總體驗證!(既然每一個字段都驗證了,就能夠對用戶提交的數據作總體驗證了!好比進行聯合惟一的驗證)

 8.最後執行相似 clean_form的post_clean方法結束驗證。(通常不使用post_clean作自定義過濾,clean_form方法徹底能夠解決)

form表單提交驗證(form表單(會發起 get)提交刷新失去上次內容)

from django.shortcuts import render,HttpResponse,redirect
from django.forms import Form
from django.forms import fields

class Login(Form):
                              #from驗證規則 用戶名 6-10字符  required不能爲空
    name=fields.CharField(max_length=10,
                          min_length=6,
                          required=True,
                           error_messages={
                               'required':'用戶名不能爲空',  #error_messages參數 自定義錯誤信息
                               'min_length':'過短了',
                                'max_length': "太長了",
                                           }

                          )
                                                                    # z注意name 必須和 from表單提交的一致,要麼二則怎麼對比校驗呢
    pwd= fields.CharField(min_length=3,
                          required=True,
                          error_messages={
                              'required': '密碼不能爲空',  # error_messages參數 自定義錯誤信息
                              'min_length': '過短了',
                              'max_length': "太長了",
                          }



                          )


def index(request):
    if request.method=='GET':
        return render(request,'login.html')
    else:
        obj=Login(request.POST)  #把客戶端提交來的form表單和 和匹配規則放在一塊兒
        res=obj.is_valid()         #自動校驗  給出結果 True 或者 False
        if res:                    #驗證成功後obj.cleaned_data獲取成功的數據,字典類型正好對應數據 的批量操做
            print(obj.cleaned_data)
            return redirect('http://www.baidu.com')                 #obj.errors獲取錯誤信息(對象類型)就能夠傳到前端顯示了!
        else:
           return  render(request,'login.html',{'obj':obj})
View Code

 

Aja提交驗證(不會刷新,上次輸入內容自動保留)

Django的form驗證功能不只限於對form表單提交的數據驗證,一樣適用於ajax提交方式;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ajx提交</title>
</head>
<body>
<form method="post" action="/aja_login/" id="f1">
  {%csrf_token%}
<p>用戶:<input type="text" name="name"></p>
<p>密碼:<input type="password" name="pwd"></p>
<p><input type="button" onclick="Ajxform()" value="aja提交"></p>
</form>
</body>
<script src="/static/zhanggen.js"></script>
<script> function Ajxform(){
    $('.c1').remove()
    $.ajax({
        url:'/alogin/',
        type:'POST',
        dataType:'JSON',
        data:$('#f1').serialize(),
        success:function (args) {
            if (args.status){ }
            else{
{#                {status: false, msg: Object}#}
{#                console.log(args);#}
{#                Jquery循環服務端 傳過來的 錯誤信息對象#}
                $.each(args.msg,function (index,value) {
                    console.log(index,value);
{#                 index----> name ["過短了"]#}
{#                 value-----pwd["密碼不能爲空"]#}
                    var tag=document.createElement('span');
                    tag.innerHTML= value[0];
                    tag.className='c1';
                    console.log(index);
{#                    尋找input下 屬性爲 name 和pwd的標籤(字符串拼接) 在他們後半加 上tag標籤也就是錯誤 信息 #}
                    $('#f1').find('input[name="'+ index +'"]').after(tag)

                })
            }

               }})}
</script>
</html>
View Code

Views

from django.shortcuts import render,HttpResponse,redirect
from django.forms import Form
from django.forms import fields
import json
class Login(Form):
                              #from驗證規則 用戶名 6-10字符  required不能爲空
    name=fields.CharField(max_length=10,
                          min_length=6,
                          required=True,
                         error_messages={
                               'required':'用戶名不能爲空',  #error_messages參數 自定義錯誤信息
                               'min_length':'過短了',
                                'max_length': "太長了",
                                           }

                          )
                                                                    # z注意name 必須和 from表單提交的一致,要麼二則怎麼對比校驗呢
    pwd= fields.CharField(min_length=3,
                          required=True,
                          error_messages={
                              'required': '密碼不能爲空',  # error_messages參數 自定義錯誤信息
                              'min_length': '過短了',
                              'max_length': "太長了",})



def agx_login(request):
    ret={'status':True,'msg':None}
    if request.method=='GET':
       return render(request,'ajalogin.html')
    else:
        obj=Login(request.POST)
        ret['status']=False
        ret['msg']=obj.errors
        return HttpResponse(json.dumps(ret))
View Code

 

自定義正則表達式驗證

密碼修改實例

password_complexity='^(?:(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])).+$' #密碼複雜性要求:密碼必須包含數字、大、寫字母
{% extends "arya/layout.html" %}
{% block  out_css %}
    <link rel="stylesheet" href="/arya/static/arya/css/form-control.css"/>
{% endblock %}

{% block content %}
    {% csrf_token %}
    <div>
        <div class="row">
            <a class="btn btn-default" href="{{ request.META.HTTP_REFERER }}">返回</a>
            <div class="col-md-5 col-md-offset-3">
                <form>
                    <div class="form-group">
                        <label for="exampleInputPassword1">請輸入原始密碼</label>
                        <input name="old_pwd" type="password" class="form-control" id="exampleInputPassword0"
                               placeholder="原始密碼">
                    </div>
                    <div class="form-group">
                        <label for="exampleInputPassword1">新的密碼</label>
                        <input name="first_new_pwd" type="password" class="form-control" id="exampleInputPassword1"
                               placeholder="新的密碼">
                    </div>
                    <div class="form-group">
                        <label for="exampleInputPassword1">再次輸入新密碼</label>
                        <input name="second_new_pwd" type="password" class="form-control" id="exampleInputPassword2"
                               placeholder="再次輸入新密碼">
                    </div>

                    <button id="submit_pwd" type="button" class="btn btn-default">提交</button>

                </form>
                <br>
                <p style="color: red" id="__all__" class="error_msg"></p>
                <br>
                <p>設置密碼時請符合如下規則:最小長度八、包含大小寫英文字母、數字。</p>
            </div>
        </div>
    </div>
    {#    </section>#}
    <script>
        $('#submit_pwd').click(function () {
            var $csrf = $("[name='csrfmiddlewaretoken']").val();
            var $old_pwd = $('[name="old_pwd"]').val();
            var $first_new_pwd = $('[name="first_new_pwd"]').val();
            var $second_new_pwd = $('[name="second_new_pwd"]').val();

            var pwd_formdata = new FormData();
            pwd_formdata.append('csrfmiddlewaretoken', $csrf);
            pwd_formdata.append('old_pwd', $old_pwd);
            pwd_formdata.append('first_new_pwd', $first_new_pwd);
            pwd_formdata.append('second_new_pwd', $second_new_pwd);


            $.ajax({
                type: 'post',
                data: pwd_formdata,
                processData: false,
                contentType: false,
                success: function (data) {
                    var response = JSON.parse(data);
                    var $error_p = $('<p class="error_msg" style="color:red">'+ '</p>');

                    if (response.status == 200) {
                        window.location = "/login/"
                    }

                    if (response.status == 404) {
                        var error_p =$error_p.text(response.msg.old_pwd);
                        $('[name="old_pwd"]').after(error_p)
                    }
                    else {
                        $.each(response.msg, function (k, v) {
                            var $input_tag = $("[name=" + k +"]");
                            var error_p = '<p style="color: red" class="error_msg">'+v[0]+'</p>';
                            $input_tag.after(error_p);
                            console.log(response.msg);
                            if (k == '__all__') {
                                $('#__all__').text(v[0])
                            }
                        });
                    }

                    setTimeout("$('.error_msg').remove()", 3000);

                }
            })


        })
    </script>

{% endblock %}
前端模板
def changepwd(request):  #修改密碼視圖
    if request.method=='POST':
        current_user = request.session.get('username')
        response_info = {'status':200,'msg':None}
        user_db_obj = models.UserInfo.objects.filter(username=current_user).first()
        if not user_db_obj or user_db_obj.password != make_md5(request.POST.get('old_pwd').strip()):
            response_info['status'] = 404
            response_info['msg'] = {'old_pwd': '原始密碼錯誤.'}
        else:
            obj = FormCheck.Set_password(request.POST)
            if not obj.is_valid():
                response_info['status'] = 403
                response_info['msg']=obj.errors
            else:
                user_db_obj.password = make_md5(request.POST.get('second_new_pwd').strip())
                user_db_obj.save()
        return HttpResponse(json.dumps(response_info, ensure_ascii=False))
    return render(request,'woke_order/changepwd.html')
Django視圖
from django.forms import Form
from django.forms import fields
from django.forms import widgets
from cmdb.models import *
import re
from django.core.exceptions import ValidationError

class Set_password(Form):
    password_complexity='^(?:(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])).+$'

    old_pwd=fields.RegexField(password_complexity,
        required=True,
        min_length=8,
        error_messages={'invalid':'不知足密碼複雜性要求','required':'密碼不能爲空!','min_length':'密碼長度少於8位'},
    )

    first_new_pwd=fields.RegexField(password_complexity,
        required=True,
        min_length=8,
        error_messages={'invalid':'不知足密碼複雜性要求','required':'密碼不能爲空!','min_length':'密碼長度少於8位'},
    )

    second_new_pwd =fields.RegexField(password_complexity,
        required=True,
        min_length=8,
        error_messages={'invalid':'不知足密碼複雜性要求','required':'密碼不能爲空!','min_length':'密碼長度少於8位'},
    )

    def clean(self):
        first_new_pwd=self.cleaned_data.get('first_new_pwd')
        second_new_pwd=self.cleaned_data.get('second_new_pwd')
        if first_new_pwd and second_new_pwd:
            if first_new_pwd.strip() == second_new_pwd.strip():
                return self.cleaned_data
        raise ValidationError("兩次密碼不一致")
Django的form驗證

 

IP 和端口

ipaddr_validate="^((?:(2[0-4]\d)|(25[0-5])|([01]?\d\d?))\.){3}(?:(2[0-4]\d)|(255[0-5])|([01]?\d\d?))$"
port_validate='^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$'
from django.forms import Form,fields
from django.forms import widgets,forms
import re
ipaddr_validate="^((?:(2[0-4]\d)|(25[0-5])|([01]?\d\d?))\.){3}(?:(2[0-4]\d)|(255[0-5])|([01]?\d\d?))$"
port_validate='^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$'
class dbinfo_create(Form):
    data_mode_type=fields.CharField(required=True,error_messages={'required':'數據庫模型不能爲空.'})
    database_type=fields.CharField(required=True,error_messages={'required':'數據庫類型不能爲空'})
    host=fields.RegexField(ipaddr_validate,required=True,error_messages={'required':'IP不能爲空','invalid':'不合法的IP地址'})
    port=fields.RegexField(port_validate,required=True,error_messages={'required':'端口不能爲空.','invalid':'端口無效'})
    # instance_nikename=fields.CharField(max_length=20,error_messages={'required':'端口不能爲空.',"max_length":"標題不能超過20個字"})
    db_business=fields.CharField(required=True,error_messages={'required':'請說明所屬業務線'})
    DBA=fields.CharField(required=True,error_messages={'required':'請說明DBA'})
    responsible_person=fields.CharField(required=True, error_messages={'required':'請選擇相關責任人!'})
驗證

 

 

 

 

 

二、動態生成HTML標籤,保留用戶上次輸入的內容。

如何保留用戶上次輸入的內容?

因爲form表單submit以後(發送post請求) 數據提交到 後端,無論前端輸入的數據是否正確,服務端也要響應,因此頁面會刷新;

因此沒法保留用戶上次輸入的內容;如何解決呢?

 

一、把定義的定義的Form類,實例化(obj=Login() )內部調用一個__str__的方法,若是沒有傳值 返回<input type="text" name=「字段」>name='字段名空的input標籤

二、把這個實例化以後的對象傳到前端顯示,讓用戶輸入值;用戶輸入值經過post方法提交到後臺。

三、若是後臺實例化一個對象 obj=Login(request.POST)傳入了值, <input type="text" name=「字段」 value='request.post的數據'>而後後端再返回客戶端就能夠看到用戶輸入的值了!

 

 

 

保留用戶上次輸入的內容 是利用了 obj=Login(request.POST)接收了用戶輸入的值

視圖

from django import  forms

class Myform(forms.Form):            #一、寫1個繼承forms.Form的類,定製form表單的數據類型;
    user=forms.CharField(max_length=32,min_length=3,label='用戶名',
                         error_messages={'required':'不能爲空'},
                         widget=forms.TextInput(attrs={'class':'sb','placeholder':'用戶名'},)
                         )
    age=forms.IntegerField(label='年齡',error_messages={'required':'不能爲空'},)
    email=forms.EmailField(label='郵箱',error_messages={'required':'不能爲空'},)

def register2(request):
    if request.method=='GET':
        forms_obj=Myform()               #二、實例化類,把對象渲染到模板
        return render(request,'form——register.html',{'forms_obj':forms_obj})
    else:
        forms_obj=Myform(request.POST)   #三、把提交的數據封裝成form對象
        if forms_obj.is_valid():         #四、使用 form對象的.is_valid()方法,校驗提交過來的數據是否符合驗證規則
            data=forms_obj.cleaned_data  #五、獲取驗證經過的數據(字典類型,可直接 **dict插入數據庫)
            # User.objects.create_user(**data)
            return HttpResponse('OK')
        else:
            print(forms_obj.cleaned_data) #六、因爲用戶在form表單提交了值,利用這一點,
                                            # 把forms_obj=Myform(request.POST)渲染到前端就能夠保存用戶輸入的值
        return render(request, 'form——register.html', {'forms_obj':forms_obj})
View Code

前臺

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Django_form驗證</title>
</head>
<body>
<form action="/form/" method="post" novalidate>
    {% csrf_token %}
    <p>用戶:{{ forms_obj.user }}{{ forms_obj.errors.user.0 }}</p>
      <p>年齡:{{ forms_obj.age }}{{ forms_obj.errors.age.0}}</p>
    <p>郵箱:{{ forms_obj.email }}{{ forms_obj.errors.email.0}}</p>
    <button>提交</button>
</form>
</body>
</html>
View Code

 

 

from django.shortcuts import render,HttpResponse,redirect
from django.forms import Form
from django.forms import fields
import json
class Login(Form):
                              #from驗證規則 用戶名 6-10字符  required不能爲空
    name=fields.CharField(max_length=10,
                          min_length=6,
                          required=True,
                         error_messages={
                               'required':'用戶名不能爲空',  #error_messages參數 自定義錯誤信息
                               'min_length':'過短了',
                                'max_length': "太長了",
                                           }

                          )
                                                                    # z注意name 必須和 from表單提交的一致,要麼二則怎麼對比校驗呢
    pwd= fields.CharField(min_length=3,
                          required=True,
                          error_messages={
                              'required': '密碼不能爲空',  # error_messages參數 自定義錯誤信息
                              'min_length': '過短了',
                              'max_length': "太長了",})


def index(request):
    ret={'status':True,'msg':None}
    if request.method=='GET':
        obj=Login()                 #自動生成空白的input標籤 發送給客戶端)
        return render(request,'login.html',{'obj':obj})
    else:
        obj=Login(request.POST)  #把客戶端提交來的form表單和 和匹配規則放在一
        res=obj.is_valid()         #自動生成空白的input標籤 發送
        if res:                    #驗證成功後obj.cleaned_data獲取成功的數據,字典類型正好對應數據 的批量操做
            return HttpResponse('OK') #obj.errors獲取錯誤信息(對象類型)就能夠傳到前端顯示了!
        else:
           return render(request,'login.html',{'obj':obj})
View Code
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登陸頁面</title>
</head>
<body>
<form method="post" action="/login/" id="f1" novalidate >
     {%csrf_token%}
       <h1>用戶登陸</h1>
        <p>用戶名 {{obj.name}}{{ obj.name.errors.0}}</p>
        <p>密碼:{{ obj.pwd}}{{ obj.pwd.errors.0}}</p>
        <p><input type="submit" value="登陸"></p>
</form>
</body>
</html>
View Code

 

 

 

 三、承上啓下 form組件的套路(執行流程):

(1)在後端定義類和字段,實例化Form類;

(2)到用戶 發送get請求時,服務端渲染到模板(空標籤/默認值)發送到客戶端顯示

(3)客戶端填數據,POST提交到後端;

(4)後端驗證,返回結果給前端;(切記Form組件是在後端生成,發送給客戶端顯示,客戶端填完數據在發回服務端!)

 

2、form組件使用:

一、導入Form插件

from django.forms import Form,fields
from django.forms import widgets
class Class_form(Form):
    title=fields.RegexField('全棧\d+',
                            # initial='全棧', #設置input標籤中的默認值
                            min_length=2,
                            required=True,
                            error_messages={'invalid':"必須以全棧開頭",
                                            'min_length':'過短了',
                                            'required':"不能爲空",
                                            }
                            )
class Students(Form):
    name=fields.CharField(required=True,
    widget=widgets.TextInput(attrs={'class':'form-control'}),
    error_messages={'required':'姓名不能爲空'})
    sex=fields.CharField(required=True,error_messages={'required':'不能爲空'},
    widget = widgets.TextInput(attrs={'class': 'form-control'})

                         )
    cls_id=fields.IntegerField(widget=widgets.Select(choices=models.Classes.objects.values_list('id','title'),
    attrs = {'class': 'form-control'}

                                                     ),

                                )
class teacher_form(Form):
    tname=fields.CharField(required=True,error_messages={'required':"姓名不能爲空"} )
   #  classes=fields.CharField( #多選 不能用這個插件不使用request.post.getlist()取值
   #      widget=widgets.Select(choices=models.Classes.objects.values_list(),
   #      attrs={'multiple':'multiple'})
   #                           )
   #  classes=fields.CharField(widget=widgets.SelectMultiple(
   # # 若是在fields.CharField字段該插件,獲得會是{'tname': 'ww', 'classes': "['2', '3']"}字符串
   #   choices= models.Classes.objects.values_list('id','title')) )
    classes=fields.MultipleChoiceField(
        choices=models.Classes.objects.values_list('id','title'),
        widget=widgets.SelectMultiple,error_messages={'required':'選擇不能爲空'})
    def __int__(self,*args,**kwargs):  #解決數據不一樣步的bug,每次form組件實例化時 都從新去數據庫拿數據
        super(teacher_form,self).__init__(*args,**kwargs)
        self.fields['classes'].widget.choices=models.Classes.objects.values_list('id','title')



class Test_form(Form):
    name=fields.CharField()  #動態生成 text類型的input標籤
    text=fields.CharField(widget=widgets.Textarea,) #動態生成文本框
    age=fields.CharField(widget=widgets.CheckboxInput) #動態生成單選框
    holby=fields.MultipleChoiceField(                  #MultipleChoiceField動態生成複選框
        choices=[(1,'籃球'),(2,"足球"),(3,"高俅")],
        widget=widgets.CheckboxSelectMultiple)
    sex=fields.MultipleChoiceField(
        choices=[(1,''),(2,'')],
        widget=widgets.RadioSelect
    )

    select=fields.ChoiceField(choices=[(2, '北京'), (3, '唐縣')]) #經過ChoiceField字段動態生成單選框
                                                                   # 經過form組件的MultipleChoiceField字段
    mselect=fields.MultipleChoiceField(choices=[(1,'管家佐'),(2,'萬寶利') ],
                                 widget=widgets.SelectMultiple)
    file=fields.FileField()  #經過form組件的.FileField動態生成 文件上傳input標籤,注意在提交到後臺是對象
View Code


二、定義類和字段(驗證規則) 擴展方法

class Form_login(Form):

                 字段                               參數

  user=fields.RegexField正則表達式,驗證規則,error_messages={錯誤信息},widget=html標籤插件attrs = {'標籤插件的屬性'})

 

4、form的鉤子函數

Django的form在obj.is_valid()方法內提供2個鉤子函數,以便咱們隨時調用他自定製一些複雜的驗證規則;

 

 局部鉤子函數 

class Class_form(Form):
    title=fields.RegexField('全棧\d+',
                            # initial='全棧', #設置input標籤中的默認值
                            min_length=2,
                            required=True,
                            error_messages={'invalid':"必須以全棧開頭",
                                            'min_length':'過短了',
                                            'required':"不能爲空",
                                            }
                            )
class Students(Form):
    name=fields.CharField(required=True,
    widget=widgets.TextInput(attrs={'class':'form-control'}),
    error_messages={'required':'姓名不能爲空'})
    sex=fields.CharField(required=True,error_messages={'required':'不能爲空'},
    widget = widgets.TextInput(attrs={'class': 'form-control'})

                         )
    cls_id=fields.IntegerField(widget=widgets.Select(choices=models.Classes.objects.values_list('id','title'),
    attrs = {'class': 'form-control'}

                                                     ),

                                )
class teacher_form(Form):
    tname=fields.CharField(required=True,error_messages={'required':"姓名不能爲空"} )
   #  classes=fields.CharField( #多選 不能用這個插件不使用request.post.getlist()取值
   #      widget=widgets.Select(choices=models.Classes.objects.values_list(),
   #      attrs={'multiple':'multiple'})
   #                           )
   #  classes=fields.CharField(widget=widgets.SelectMultiple(
   # # 若是在fields.CharField字段該插件,獲得會是{'tname': 'ww', 'classes': "['2', '3']"}字符串
   #   choices= models.Classes.objects.values_list('id','title')) )
    classes=fields.MultipleChoiceField(
        choices=models.Classes.objects.values_list('id','title'),
        widget=widgets.SelectMultiple,error_messages={'required':'選擇不能爲空'})
    def __int__(self,*args,**kwargs):  #解決數據不一樣步的bug,每次form組件實例化時 都從新去數據庫拿數據
        super(teacher_form,self).__init__(*args,**kwargs)
        self.fields['classes'].widget.choices=models.Classes.objects.values_list('id','title')



class Test_form(Form):
    name=fields.CharField()  #動態生成 text類型的input標籤
    text=fields.CharField(widget=widgets.Textarea,) #動態生成文本框
    age=fields.CharField(widget=widgets.CheckboxInput) #動態生成單選框
    holby=fields.MultipleChoiceField(                  #MultipleChoiceField動態生成複選框
        choices=[(1,'籃球'),(2,"足球"),(3,"高俅")],
        widget=widgets.CheckboxSelectMultiple)
    sex=fields.MultipleChoiceField(
        choices=[(1,''),(2,'')],
        widget=widgets.RadioSelect
    )

    select=fields.ChoiceField(choices=[(2, '北京'), (3, '唐縣')]) #經過ChoiceField字段動態生成單選框
                                                                   # 經過form組件的MultipleChoiceField字段
    mselect=fields.MultipleChoiceField(choices=[(1,'管家佐'),(2,'萬寶利') ],
                                 widget=widgets.SelectMultiple)
    file=fields.FileField()  #經過form組件的.FileField動態生成 文件上傳input標籤,注意在提交到後臺是對象
View Code

 全局鉤子函數

若是要想要同時對2個form字段進行驗證,就須要全局鉤子函數(應用 驗證2次輸入的密碼是否一致),能夠調用他們自定製複雜的form驗證規則,

問題1:  註冊頁面輸入爲空,報錯:keyError:找不到password

def clean(self):
        print("---",self.cleaned_data)
        #  if self.cleaned_data["password"]==self.cleaned_data["repeat_password"]:        
        #  報錯緣由:self.cleaned_data是乾淨數據,若是頁面沒有輸入內容,則self.cleaned_data沒有password。
        改以下:
        if self.cleaned_data.get("password")==self.cleaned_data.get("repeat_password"):
            return self.cleaned_data
        else:
            raise ValidationError("兩次密碼不一致")
View Code

 

 

  

4、渲染到模板

1.簡單粗暴型

注意:模板語言{{form_obj.as_p}},必定要在設置lable參數

class UserInfoForm(Form):
    name=fields.CharField(required=True,error_messages={'reqired':'用戶名不能爲空'},label='姓名') 
    email=fields.EmailField(required=True,error_messages={'reqired':'用戶名不能爲空'},label='郵箱')
    pary=fields.ChoiceField(choices=[(1,"技術部"),(2,'銷售部'),(3,'市場部'),],label='部門')

 

{{obj.as_p}}以P標籤的形式所有顯示

<table> 注意加table標籤形式所有顯示
{{obj.as_table}}
</table>


<ul>注意加ul標籤形式所有顯示
{{obj.as_table}}
</ul>
View Code

2.靈活定製型

<p>姓名:{{ obj.name }}</p>
<p>性別:{{ obj.sex }}</p>
<p>愛好: {{ obj.holby }}</p>
<p>婚姻情況:{{ obj.age }}</p>
<p>我的簡介 {{ obj.text }}</p>
<p>工做地點: {{ obj.select }}</p>
<p>居住地點:{{ obj.mselect }}</p>
<p>資料上傳:{{obj.file}}</p>
View Code

 

5、頁面顯示用戶填完數據提交回來後臺驗證

數據校驗

obj=classForm_login(request.POST )

默認校驗:obj=classForm_login(data={} ) 含有錯誤信息: obj=Class_form(initial={'title':class_obj.title})只有html標籤

obj.is_valid()  獲取校驗結果

obj.errors獲取錯誤信息

obj.cleand_data 獲取正確的數據

 

6、基於Form組件的學生管理系統(項目)

路由

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r'^classes/',views.classes),
    url(r'^classes_add(\d+)/',views.classes_add),
    url(r'^classes_edit(\d+)/',views.classes_edit),
    url(r'^students/',views.students),
    url(r'^students_add(\d+)/',views.students_add),
    url(r'^students.edit(\d+)/',views.students_edit),
    url(r'^teachers/',views.teacher),
    url(r'^teacher_add/',views.teacher_add),
    url(r'^teacher_edit(\d+)/',views.teacher_edit),
    url(r'^test/',views.test),
]
View Code

視圖

def classes(request):
    if request.method=='GET':
        c_list=models.Classes.objects.all()
        return render(request,'class_list.html',{'clist':c_list})

def classes_add(request,args):
    if request.method=='GET':
        obj=Class_form()
        return render(request,'class_add.html',{'obj':obj})
    else:
        obj=Class_form(request.POST)
        if obj.is_valid():
            models.Classes.objects.create(**obj.cleaned_data )
            return redirect('/classes/')
        else:
            print('NI')
            return render(request,'class_add.html',{'obj':obj})

def classes_edit(request,args):
    if request.method=='GET':
        class_obj=models.Classes.objects.filter(id=args).first()
        obj=Class_form(initial={'title':class_obj.title})
        return render(request,'class_edit.html',{'obj':obj,'nid':args})
    else:
        obj = Class_form(request.POST)
        if obj.is_valid():
            models.Classes.objects.filter(id=args).update(**obj.cleaned_data)
            return redirect('/classes/')
        else:
            return render(request, 'class_edit.html', {'obj': obj, 'nid': args})


def students(request):
    if request.method=='GET':
        students=models.Student.objects.all()
        return render(request,'students.html',{'student':students})

def students_add(request,nid):
    if request.method=='GET':
        obj=Students()
        return render(request,'student_add.html',{'obj':obj,'nid':nid})
    else:
        obj=Students(request.POST)
        if obj.is_valid():
            models.Student.objects.create(**obj.cleaned_data)
            return redirect('/students/')
        else:
            return render(request,'student_add.html',{'obj':obj,'nid':nid})


def students_edit(request,nid):
    if request.method=='GET':
        # print(models.Student.objects.filter(id=nid).values('name','sex','cls_id').first())
        obj=Students(initial=models.Student.objects.filter(id=nid).values('name','sex','cls_id').first())
        return render(request,'student_edit.html',{'obj':obj,'nid':nid})
    else:
        obj1=Students(request.POST)
        if obj1.is_valid():
            models.Student.objects.filter(id=nid).update(**obj1.cleaned_data)
            return redirect('/students/')
        else:
            return render(request, 'student_edit.html', {'obj': obj1, 'nid': nid})

def teacher(request):
    if request.method=='GET':
        teacher_list=models.teacher.objects.all()
        return render(request,'teacher_list.html',{'tlist':teacher_list})

def teacher_add(request):
    if request.method=='GET':
        print(request.method)
        obj=teacher_form()
        return render(request,'teacher_add.html',{'obj':obj})
    else:
        obj=teacher_form(request.POST)
        if obj.is_valid():
            classe_ids=obj.cleaned_data.pop('classes') #老師任教的班級
            tname=obj.cleaned_data   #老師的姓名
            create_teacher=models.teacher.objects.create(**tname)
            create_teacher.c2t.add(*classe_ids)
            return redirect('/teachers/')
        else:
            return render(request,'teacher_add.html',{'obj':obj})









def teacher_edit(request,arg):
    if request.method=='GET':
        teacher_obj=models.teacher.objects.filter(id=arg).first()
        classes_ids=teacher_obj.c2t.values_list('id')
        cid_list=list(zip(*classes_ids))[0] if list(zip(*classes_ids)) else[]
        # print(cid_list) 元組
        obj=teacher_form(initial={'tname':teacher_obj.tname,'classes':cid_list})
        return render(request,'teacher_edit.html',{'obj':obj,'nid':arg} )
    else:
        obj=teacher_form(request.POST)
        if obj.is_valid():
            teacher_name=obj.cleaned_data.pop('tname')
            models.teacher.objects.filter(id=arg).update(tname=teacher_name)
            obj1=models.teacher.objects.filter(id=arg).first()
            classes=obj.cleaned_data.pop('classes')
            obj1.c2t.set(classes)
            return redirect('/teachers/')
        else:
            return render(request,'teacher_add.html',{'obj':obj})








def test(request):
    if request.method=='GET':
        obj=Test_form(initial={'holby':[ 1,2],'name':'張根','text':'我來自太行山','sex':1})
        # # print(models.Student.cls.objects.values_list())
        # obj=models.Student.objects.filter(id=1).first()
        # print(obj.cls.title)
        return render(request,'test.html',{'obj':obj})
View Code

form組件

from django.shortcuts import render,HttpResponse,redirect
from  app01 import models
from django.forms import Form,fields
from django.forms import widgets

class Class_form(Form):
    title=fields.RegexField('全棧\d+',
                            # initial='全棧', #設置input標籤中的默認值
                            min_length=2,
                            required=True,
                            error_messages={'invalid':"必須以全棧開頭",
                                            'min_length':'過短了',
                                            'required':"不能爲空",
                                            }
                            )
class Students(Form):
    name=fields.CharField(required=True,
    widget=widgets.TextInput(attrs={'class':'form-control'}),
    error_messages={'required':'姓名不能爲空'})
    sex=fields.CharField(required=True,error_messages={'required':'不能爲空'},
    widget = widgets.TextInput(attrs={'class': 'form-control'})

                         )
    cls_id=fields.IntegerField(widget=widgets.Select(choices=models.Classes.objects.values_list('id','title'),
    attrs = {'class': 'form-control'}

                                                     ),

                                )
class teacher_form(Form):
    tname=fields.CharField(required=True,error_messages={'required':"姓名不能爲空"} )
   #  classes=fields.CharField( #多選 不能用這個插件不使用request.post.getlist()取值
   #      widget=widgets.Select(choices=models.Classes.objects.values_list(),
   #      attrs={'multiple':'multiple'})
   #                           )
   #  classes=fields.CharField(widget=widgets.SelectMultiple(
   # # 若是在fields.CharField字段該插件,獲得會是{'tname': 'ww', 'classes': "['2', '3']"}字符串
   #   choices= models.Classes.objects.values_list('id','title')) )
    classes=fields.MultipleChoiceField(
        choices=models.Classes.objects.values_list('id','title'),
        widget=widgets.SelectMultiple,error_messages={'required':'選擇不能爲空'})
    def __int__(self,*args,**kwargs):  #解決數據不一樣步的bug,每次form組件實例化時 都從新去數據庫拿數據
        super(teacher_form,self).__init__(*args,**kwargs)
        self.fields['classes'].choices=models.Classes.objects.values_list('id','title')



class Test_form(Form):
    name=fields.CharField()  #動態生成 text類型的input標籤
    text=fields.CharField(widget=widgets.Textarea,) #動態生成文本框
    age=fields.CharField(widget=widgets.CheckboxInput) #動態生成單選框
    holby=fields.MultipleChoiceField(                  #MultipleChoiceField動態生成複選框
        choices=[(1,'籃球'),(2,"足球"),(3,"高俅")],
        widget=widgets.CheckboxSelectMultiple)
    sex=fields.MultipleChoiceField(
        choices=[(1,'男'),(2,'女')],
        widget=widgets.RadioSelect
    )

    select=fields.ChoiceField(choices=[(2, '北京'), (3, '唐縣')]) #經過ChoiceField字段動態生成單選框
                                                                   # 經過form組件的MultipleChoiceField字段
    mselect=fields.MultipleChoiceField(choices=[(1,'管家佐'),(2,'萬寶利') ],
                                 widget=widgets.SelectMultiple)
    file=fields.FileField()  #經過form組件的.FileField動態生成 文件上傳input標籤,注意在提交到後臺是對象
View Code

 

模板

班級管理(1對1)

班級顯示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>班級列表</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.5-dist/css/bootstrap.css">
</head>
<body>
<div style="width: 500px;margin: 0 auto">
<h1>班級列表</h1>
<ul>
    {% for obj in clist %}
        <li>{{ obj.title }}
            <a href="/classes_add{{ obj.id }}/">添加</a>
            <a href="/classes_edit{{ obj.id }}/">編輯</a>
        </li>
    {% endfor %}
</ul>
</div>
</body>
</html>
View Code

添加班級

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>添加班級</title>
</head>
<body>
<h1>添加班級</h1>
<form action='/classes_add{{2}}/' method="post" novalidate>
    {% csrf_token %}
  <p>班級添加:{{ obj.title}} {{ obj.errors.title.0}}</p>
   <p><input type="submit" value="提交"></p>
</form>

</body>
</html>
View Code

編輯班級

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>編輯班級</title>
</head>
<body>
<form action="/classes_edit{{nid}}/" method="post">
    {% csrf_token %}
   <p>編輯班級:{{ obj.title }}{{obj.title.errors.0}} </p>
    <input type="submit" value="提交">
</form>
</body>
</html>
View Code

 

學生管理1對多

學生顯示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>學生管理</title>
</head>
<body>
<h1>學生管理</h1>
<ul>
    {% for row in student %}
        <li>{{row.name}}
            {{row.sex}}
            <a href="/students_add{{row.id}}/">添加</a>
            <a href="/students.edit{{row.id}}/">編輯</a>
        </li>
    {% endfor %}
</ul>
</body>
</html>
View Code

學生添加

<!DOCTYPE html>
<html lang="en">
<head>
    <h1>添加學生</h1>
    <meta charset="UTF-8">
    <title>添加學生</title>
</head>
<body>
<form action="/students_add{{ nid}}/" method="post" novalidate>
     {% csrf_token%}
<p>姓名:{{ obj.name}}{{obj.name.errors.0}}</p>
<p>性別:{{ obj.sex}}{{obj.sex.errors.0}} </p>
<p>班級:{{ obj.cls_id }}{{ obj.errors.0}}  </p>
<p><input type="submit" value="提交"></p>
 </form>
</body>
</html>
View Code

學生編輯

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>老師編輯</title>
</head>
<body>
<form action="/teacher_edit{{ nid }}/" method="post">
    {% csrf_token %}
<p>老師姓名:{{obj.tname }}</p>
<p>班級:{{ obj.classes }}</p>
<input type="submit" value="提交">
</form>
</body>
</html>
View Code

 

 老師管理多對多

老師顯示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>老師列表</title>
</head>
<body>
<table border="1">
<thead>
<tr><td>ID</td><td>老師</td><td>任教班級</td><td colspan="3">操做</td></tr>
</thead>
<tbody>
     {% for teacher in tlist %}
    <tr>
        <td>{{ teacher.id }}</td>
        <td>{{teacher.tname}}</td>
        <td>
            {% for row in teacher.c2t.values %}
            {{ row.title }}
            {% endfor %}
         </td>
        <td><a href="/teacher_add/">添加</a></td>
        <td><a href="/teacher_edit{{ teacher.id}}/">編輯</a></td>
    </tr>
    {% endfor %}
</tbody>
</table>



</body>
</html>
View Code

老師添加

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>添加老師</title>
</head>
<body>
<form action="/teacher_add/" method="post" novalidate>
{% csrf_token %}
<p>老師姓名:{{ obj.tname }}{{obj.tname.errors.0}}</p>
<p>任教班級:{{ obj.classes }}{{obj.classes.errors.0}}</p>
<p><input type="submit" value="提交"></p>
 </form>
</body>
</html>
View Code

老師編輯

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>老師編輯</title>
</head>
<body>
<form action="/teacher_edit{{ nid }}/" method="post">
    {% csrf_token %}
<p>老師姓名:{{obj.tname }}</p>
<p>班級:{{ obj.classes }}</p>
<input type="submit" value="提交">
</form>
</body>
</html>
View Code

 

 PS:Form驗證組件驗證ajax提交的json

Django的form組件,不只能夠對 瀏覽器端 提交過來的form表單數據作驗證,還能夠對ajax提交的 json數據 作驗證,可是須要在發送以前獲取CSRF-tocken設置在請求頭中;

 $.ajax({
                type: 'POST',
                async: false,
                cache: false,
                url: '{% url "instance_add" %}',
                 headers:{"X-CSRFToken":$.cookie('csrftoken')},
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                traditional:true,
                data:JSON.stringify({
                    "data_mode_type": $data_mode_type,
                    'database_type': $database_type,
                    'host': $host,
                    'port': $port,
                    'instance_nikename': $instance_nikename,
                    'db_business': $db_business,
                    'DBA': $DBA,
                    'responsible_person': $responsible_person
                }),
                success: function (data) {
                   alert(1)
                }
            });
        })
前端
from django.shortcuts import render,HttpResponse,redirect
from DB_auto.form_validate.add_dbinfo import dbinfo_create
import json

def instance_add(request):
    if request.method=='POST':
        json_data=json.loads(request.body.decode('utf-8'))
        obj=dbinfo_create(json_data)
        if obj.is_valid():
            print(obj.cleaned_data)
        else:
            print(obj.errors)
    return render(request,'add_dbinfo.html')
django後臺

 

 

 

 7、ModelForm

使用Django開發web程序階段回顧:

1.手動對單表進行增、刪、該、查,手動把ORM操做獲取的數據渲染到模板;(階段1)

2.Form組件(類),自動生成標籤(input、select),並對用戶輸入的數據作規則驗證;(階段2)

 

3.ModelForm顧名思義就Form和Django的Model數據庫模型結合體,能夠簡單、方便得對數據庫進行增長、編輯操做和驗證標籤的生成

 

Form組件和ModelForm的區別

ModelForm是Django Model.py和Form組件的結合體,能夠簡單/快速使用 Form驗證和數據庫操做功能,但不如Form組件靈活,若是在使用Django作web開發過程當中驗證的數據和數據庫字段相關(能夠對錶進行增、刪、改操,注意 Many to many字段,也能夠級聯操做第3張關係表;),建議優先使用ModelForm,用起來更方便些,可是在使用ModelForm的時候慎用fields='__all__',獲取數據庫全部字段勢必形成性能損耗;

 

使用ModelForm

前端:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ form_obj.as_p }}
{#<p>姓名:{{form_obj.name  }}</p>#}
</body>
</html>
View Code

 

後端視圖:

from app02 import models
from django.forms import ModelForm
class UserModalForm(ModelForm):
    class Meta:
        model=models.UserInfo #(該字段必須爲 model  數據庫中表)
        fields= '__all__'   #(該字段必須爲 fields 數據庫中表)

def add(request):
     # 實例化models_form
    if request.method=='GET':
        obj = UserModalForm()
        return render(request,'rbac/user_add.html',locals())
    else:
        obj=UserModalForm(request.POST)
        if obj.is_valid():
            data=obj.cleaned_data
            obj.save()  #form驗證經過直接 添加用戶信息到數據庫
        return render(request, 'rbac/user_add.html', locals())
View Code

 

 model.py

 

使用使用Form組件和ModelForm注意事項:

一、model.py一點要寫verbose_name='名稱'參數,纔會在前端顯示P標籤的標題;

from django.db import models

class Department(models.Model):
    title=models.CharField(max_length=32,verbose_name='部門名稱')
    def __str__(self):
        return self.title

class UserInfo(models.Model):
    name=models.CharField(max_length=32,verbose_name='姓名')
    emai=models.EmailField(max_length=32,verbose_name='郵箱')
    pary=models.ForeignKey(Department,verbose_name='部門')
View Code

 

若是使用Form組件在前端顯示標題,能夠設置Form類中的lable參數

class UserInfoForm(Form):
    name=fields.CharField(required=True,error_messages={'reqired':'用戶名不能爲空'},label='姓名')
    email=fields.EmailField(required=True,error_messages={'reqired':'用戶名不能爲空'},label='郵箱')
    pary=fields.ChoiceField(choices=[(1,"技術部"),(2,'銷售部'),(3,'市場部'),],label='部門')
View Code

 

 

二、pary=fields.ChoiceField(choices=models.Department.objects.values_list('pk','title'),label='部門'),前端select標籤不能隨數據庫操做實時更新;

在Department表添加一條數據以後,前端select標籤中的數據不能隨數據庫實時更新;

 

緣由:

不論是ModelForm仍是Form組件本質就是個類,fields(字段)本質就是類中的1個靜態屬性,在類第一次加載時賦值,永遠不會更新;

 

 

 

解決方案1(手動檔):

重寫__init__方法,每次實例化對象,就去獲取一次數據庫內容,從新賦值;

class UserInfoForm(Form):
    name=fields.CharField(required=True,error_messages={'reqired':'用戶名不能爲空'},label='姓名')
    email=fields.EmailField(required=True,error_messages={'reqired':'用戶名不能爲空'},label='郵箱')
    pary=fields.ChoiceField(label='部門')
    # pary=fields.ChoiceField(choices=models.Department.objects.values_list('pk','title'),label='部門')
    def __init__(self,*args,**kwargs):
        super(UserInfoForm,self).__init__(*args,**kwargs)
        self.fields['pary'].choices=models.Department.objects.values_list('pk','title')
View Code

 

解決方案2(自動檔)

導入ModelChoiceField 模塊  from django.forms.models import ModelChoiceField 

使用ModelChoiceField 字段

from django.forms import fields
from django.forms import widgets
from django.forms import ModelForm
from django.forms.models import ModelChoiceField

class UserInfoForm(Form):
    name=fields.CharField(required=True,error_messages={'reqired':'用戶名不能爲空'},label='姓名')
    email=fields.EmailField(required=True,error_messages={'reqired':'用戶名不能爲空'},label='郵箱')
    #方案1
    pary=ModelChoiceField(queryset=models.Department.objects.all(),label='部門')
View Code

 

自動擋雖好,可是也有缺陷;前端option標籤的內容,須要藉助model.py中的__str__方法,生成;

 

 

 

 

8、擴展 widgets之富文本編輯框

 若是你的web應用涉及到了發表文章、表情評論就必須使用富文本編輯框,小編調研了兩款 Kindeditor、CKeditor;

 

Kindeditor

1.Kindeditor簡介

http://kindeditor.net/docs/usage.html

2.下載Kindeditor編輯器

http://www.kindsoft.net/down.php

3.引入Kindeditor編輯器

<script src="/static/kindeditor-4.1.10/kindeditor-all.js"></script>

 

4.使用Kindeditor編輯器

 

a.建立textarea 標籤

<textarea name="content" id="a" cols="30" rows="10"></textarea>

b.初始化Kindeditor

<script>
  var edit=KindEditor.create('#a',{
        width:'700px',
        height:'500px',
        uploadJson:'/upload_file/',
        extraFileUploadParams:{
            'csrfmiddlewaretoken':'{{ csrf_token }}',}})
</script>

 

c. Kindeditor功能定製

<script>
        var edit = KindEditor.create('#a', {
            items: [ //填寫本身想要的功能
                'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', 'italic', 'underline',
                'removeformat', '|', 'justifyleft', 'justifycenter', 'justifyright', 'insertorderedlist',
                'insertunorderedlist', '|', 'emoticons', 'image', 'link'],
            width: '700px',
            height: '500px',
            uploadJson: '/upload_file/',
            extraFileUploadParams: {
                'csrfmiddlewaretoken': '{{ csrf_token }}',
            }
        })
    </script>

 

d.kindeditor的API

// 取得HTML內容
html = editor.html();

// 同步數據後能夠直接取得textarea的value
editor.sync();
html = document.getElementById('editor_id').value; // 原生API
html = K('#editor_id').val(); // KindEditor Node API
html = $('#editor_id').val(); // jQuery

// 設置HTML內容
editor.html('HTML內容');

 

CKeditor結合Django Form

1.下載  django-ckeditor 和pillow

pip install django-ckeditor 
pip install pillow

2.setings

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rbac.apps.RbacConfig',
    'arya.apps.AryaConfig',
    'cmdb.apps.CmdbConfig',
    'rest_framework',
    'ckeditor',
    # 'ckeditor_uploader'
]

 

CKEDITOR_CONFIGS = {
    'default': {
        'toolbar': (
            # ['div','Source','-','Save','NewPage','Preview','-','Templates'],
            # ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print','SpellChecker','Scayt'],
            # ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
            # ['Form','Checkbox','Radio','TextField','Textarea','Select','Button', 'ImageButton','HiddenField'],
            # ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'],
            # ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'],
            # ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
            # ['Link','Unlink','Anchor'],
            ['Smiley',],

            # ['Styles','Format','Font','FontSize'],
            # ['TextColor','BGColor'],
            # ['Maximize','ShowBlocks','-','About', 'pbckcode'],

        ),
    }
}
功能定製

 

3. 收集Django 項目全部 靜態文件  到的目錄static目錄   /   直接下載ckeditor到項目static

python  manage.py collectstatic

#設置媒體文件的上傳的路徑
MEDIA_URL="/media/"
#MEDIA_ROOT=os.path.join(BASE_DIR,"media")
MEDIA_ROOT='/tmp/cmdb_media/'



STATIC_ROOT = os.path.join(BASE_DIR, 'static')
設置media路徑+static路徑

 

注意:此步驟若是提示 須要你設置MEDIA_URL目錄 和STATIC_ROOT 就先暫且設置一下,最終目的是把CKeditor的js插件copy到你的靜態文件存放目錄下;

 

4.後端生成 textarea +加前端 ckedit 插件生成 富文本編輯

from ckeditor.widgets import CKEditorWidget
class comment(Form): #評論框
    content =fields.CharField(widget=CKEditorWidget)
 {{ obj.content|safe }}

<script src="/static/pligin/ckeditor/ckeditor-init.js"></script>
<script src="/static/pligin/ckeditor/ckeditor/ckeditor.js"></script>
View Code

 

5.CKEditorWidget API

  <script>
        $('.root_reply_btn').click(function () {
            var $reply_user = $(this).attr('name');
            var $pid = $(this).attr('pid');
            $('#comment_submit').attr('pid', $pid);
            CKEDITOR.instances.id_content.insertText('回覆' + $reply_user + ':');
            CKEDITOR.instances.id_content.insertHtml('<br>');
            CKEDITOR.instances.id_content.focus(); #使CKEditorWidget進入編輯狀態 (MD在後臺測試了半天!!)


        });
CKEDITOR.instances.id_content.document.$.body.firstChild.textContent 獲取p標籤的文本內容
</script>

 

6.完成效果

 

 

 

 

 

 

 

 

 

 

 

 

博客連接:http://www.cnblogs.com/wupeiqi/articles/6144178.html

http://www.cnblogs.com/yuanchenqi/articles/7439088.html#3770465

DjangoForm補充:http://www.cnblogs.com/yuanchenqi/articles/7487059.html

相關文章
相關標籤/搜索